分类 JavaScript 相关 下的文章

javascript:void(0) 你知道为什么这么写吗?

经常看到 html 页面中的 a 的 href 是这个值: javascript:void(0).

这个可以这么翻译: 它的协议是 javascript协议, 后面的javascript表达式是 void(0).
void 是 javascript 的一个操作符, 后面跟一个表达式. 不论表达式的最终结果是什么, 这个 void 操作符都返回 undefined.
浏览器发现 href 的值是 javascript 的undefined, 那么就不执行任何操作, 也不跳转.

a 的 href 常见的值有:

  1. href="https://example.com/s.php" //跳到另外一个网站s.php页面 页面刷新
  2. href="d.jsp" //跳到一个相对路径 d.jsp 页面刷新
  3. href="#top" //跳到锚点 top 页面不刷新
  4. href="#" //一般跳到页面顶端 页面不刷新
  5. href="" // 空值, 相当于当前页面, 页面刷新

继续前面的 javascript:void(0)
既然前面说了, 只要返回的是 undefined, 这个链接就打到不刷新的效果, 为何不用下面这2种方式呢?

  1. href="undefined" //这个undefined不属于javascript的, 它让浏览器跳转到相对路径为 undefined 的页面
  2. href="javascript:undefined" // 这个应该是和 javascript:void(0) 效果一样的

但是 undefined 在javascript中, 不是一个保留的关键字, 所以 它可以在非全局的命名空间中被用作变量名. 详情参看 这里
如果你再 html 中直接写 href="javascript:undefined" 那么, undefined 肯定是js中那个全局的 undefined值, 所以效果是和 void(0) 一致的. 只是怕出错而已.

另外 void(0) 和 void 0, void 1, void("hello world") 又有什么区别?
表达式加 (), 只是为了可读性. 既然不论表达式怎么执行, 返回都是 undefined, 其实表达式无所谓, 可以随便写.

一般情况下, 用 href="javascript:void(0)" 的地方, 都是不想执行这个默认的跳转链接, 而是通过 click 事件来决定跳转或提交.
既然用click 事件, 为什么不用 button 呢?

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 了, 需要手动解封:
请输入图片描述
请输入图片描述