分类 JavaScript 相关 下的文章

Javascript 添加事件 传入参数 闭包

在用javascript开发html页面的时候, 我们经常遇: 遍历一个某些DOM 结点, 给它添加event, 代码大概如下

var nodeValue = null;
for (var i in domNodes) {
    nodeValue = domNodes[i].val();
    domNodes[i].click(function(){
        //do something, but we need to nodeValue to identify
        console.log(nodeValue);
    });
}

运行下来, 发现所有的click事件, 传入的都是最后一次loop的nodeValue 值.

这是为什么?

nodeValue 作为一个local variable, 一般情况下执行完这段代码, 它的生命周期就应该结束了, 它就在内存不存在了, 可是在这段代码, click事件的这个匿名函数却在内部使用了这个值, 形成了闭包, 所以它的生命周期被延长. 同时这个匿名函数在这里只是被定义, 并不被执行(当触发click事件时候, 才会执行). 这个Loop 在最后一次循环后, 它的值被最后确定为最后一个loop的值, 当有click事件被触发时候, 它的值自然是最后一次赋的值. 

如何解决?

那么我们要现在要解决的是: 传入这次循环时候的值, 而不是最后的值. 同时, 这个click 方法接受的是一个 function. 方法如下: 

domNodes[i].click(function(curValue){

return function(){
    //do something, but we need to curValue to identify
    console.log(curValue);
};

}(nodeValue););

首先定义一个匿名函数, 并且声明一个形参, 同时执行这个匿名函数(通过后面加()执行). 那么这个当前值就被传入了. 同时在这个外层匿名函数内部返回一个匿名function, 同时这个内部函数使用了外部函数传入的值, 那么这个外部传入的值的生命周期被延长, 形成闭包, 那么就可以在真正触发click事件的时候使用到了这个值. 

javascript 正则表达式 链接

Javascript的正则表达式有2种写法

var re = /ab+c/;                  //(1)
var re = new RegExp("ab+c");      //(2)

第一种写法, 要求写程序的时候, 必须知道正则表达式的值, 也是在脚本被load 到页面的时候编译, 编译后为常量.
第二种写法, 表达式可以为常量, 也可以为变量, 是在运行时编译的.

链接:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions

html 元素转成 canvas, 然后在转成图片

这里记录最近研究如何做页面图片处理的一些知识链接:

js 处理图片的类库:
http://www.pixastic.com/lib/docs/

js 转换html 元素为 canvas, 转换为图片的类库:
http://html2canvas.hertzen.com/

有关跨域的处理
https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image

其他:
html, canvas, image
http://www.html5canvastutorials.com/tutorials/html5-canvas-image-size/
html5 canvas API:
http://www.w3schools.com/tags/ref_canvas.asp
html 5 canvas 教程:
http://www.html5canvastutorials.com/advanced/html5-canvas-save-drawing-as-an-image/
jsfiddle 在线例子:
http://jsfiddle.net/Sq7hg/2/
中文关于 CORS的一篇比较好的文章:
http://blog.csdn.net/hfahe/article/details/7730944

JavaScript 遍历页面链接, 并全部打开

接上一篇 路由器上 nginx 博客添加 fastcgi 缓存, 虽然有了缓存, 但是第一次访问的时候, 仍然比较慢, 怎么才能让用户永远点不到第一次呢? 就是服务器自己要 warmup, 如何让自己的博客系统 warmup 呢, 可以自己先遍历页面一遍.

打开 chrome 浏览器的 console, 执行如下代码(按需修改):

// 打开新的浏览器 tab, 并且返回 tab 的句柄
function openInNewTab(url) {
  var win = window.open(url, '_blank', "left=300,screenX=100,resizable,scrollbars,status");
  win.focus();
  return win;
}

var newLink;
var most = 10;  //最多并存的 tab
var winArr = new Array();   // 存放 tab 句柄的数组
var allLinks = $$("a");   // 得到所有的页面链接, 不是 jQuery方式哦
var cur = 0;
var urlMap = {};

// 间隔时间执行的函数
function loopStart() {
    try {
        newLink = allLinks[cur++].href;

        if (urlMap[newLink]) {
            // 已经打开过, do nothing, just continue
        } else {
            urlMap[newLink] = "yes"; //放入 map,表示处理过
            if (most < winArr.length) {  //达到最多, 关闭最早
                winArr.shift().close();
            }
                        // 只处理本站的链接
            if (newLink.indexOf("tianxiaohui.com") > 0) {
                console.log(newLink);
                winArr.push(openInNewTab(newLink));
            }
        }
        setTimeout(loopStart, 1000);
    } catch (ex) {
        console.log(ex);
    }
}

setTimeout(loopStart, 1000);

可能会遇到一个问题, 就是新页面打不开, 会出现如下状况, 这个页面默认被 block 了, 需要手动解封:
请输入图片描述
请输入图片描述

浏览器控制台 $ 符号

接上一篇 检查 jQuery 是否 load, 否则重新加载 , 做了一个加载 jQuery 的实验, 找了一个未加载 jQuery 的页面, 再控制台检查 window.jQuery, 显示 undefined, 但是如果直接输出 $, 却是有输出的(默认以 chrome console 为例):

>window.jQuery;
undefined
>$;
function $(selector, [startNode]) { [Command Line API] }

这里就有点迷惑了, 为什么不加载 jQuery, $ 也是 JavaScript 的对象呢? 难道加载了 extJS 等 JavaScript library? 换一个空白页面, 仍然是上面的输出. 真奇了怪了.
那么我们先看看如果加载了 jQuery, 输出又是什么样子呢?

>if(!window.jQuery)
{
   var script = document.createElement('script');
   var protocol = (("https:" == document.location.protocol) ? " https" : " http");
   script.src = protocol + "://code.jquery.com/jquery-1.9.1.min.js";
   script.type = "text/javascript";
   (document.getElementsByTagName('body')[0] || document.getElementsByTagName('head')[0]).appendChild(script);
}
<script src=​" https:​/​/​code.jquery.com/​jquery-1.9.1.min.js" type=​"text/​javascript">​</script>​
>window.jQuery;
function (e,t){return new b.fn.init(e,t,r)} 
>$;
function (e,t){return new b.fn.init(e,t,r)} 

这里 window.jQuery 和 $ 都有了, 值是一样的, 并且 $ 和上面的输出是不一样的.
为了解开迷惑, 就 google 之, 于是发现了这个非常有趣的帖子, 大致翻译过来如下:

问: 几年前, 哥也曾是 JavaScript/jQuery 开发攻城狮, 如今重操旧业. 清醒的记得, $符号是用在 jQuery 的库里面的, 如果不用 jQuery, $这逼, 啥都不是. 
今天, 我打开一个不包含任何 JavaScript 库的空页面, 然后在控制台输出 $, 竟然输出了一些东西, 不是 undefined, 是一个 function. 
1) 以前$符号是没有赋予任何函数的, 难道是我记错了?
2) 如果没有 load jQuery 等类库, 那么$符号代表神马?

答: 
1) 以前你是对的, 现在依然是对的;
2) Firefox and Chrome implement $, $$ and several others as helper commands. Both will set $$ to document.querySelectorAll(), and set $ to document.querySelector if window.$ hasn't been defined.

那么谜底解开, 在 firefox 和 chrome 的控制台, 这些符号默认被赋予了一些特定的函数, 所以即使没有 load jQuery 等类库, 你也可以用他们来操作 DOM.

  1. $() 对于给定的表达式进行评估, 如果找到对应的 element, 就返回第一个元素, 相当于 document.querySelector();
  2. $$() 评估表达式, 返回找到的所有 node 的数组, 相当于 document.querySelectorAll();
  3. $x() 评估 xPath 表达式, 返回找到 node 的数组;

还有更多, 参考官方这里: Firefox, Chrome.