NodeList集合跟Array数组的区别

首先来看看什么是NodeList,NodeList跟arguments都不是普通的数组,他们有数组的一些基本属性但是又不完全是数组。下面是在Mozilla上面找到的定义:

This is a commonly used type which is a collection of nodes returned by getElementsByTagName, getElementsByTagNameNS, and Node.childNodes. The list is live, so changes to it internally or externally will cause the items they reference to be updated as well. Unlike NamedNodeMap, NodeList maintains a particular order (document order). The nodes in a NodeList are indexed starting with zero, similarly to JavaScript arrays, but a NodeList is not an array.
由字面意思来看NodeList是DOM操作(getElementsByTagName等)取出来的集合,是集合而不是普通的数组,但是他们有数组的一些属性,例如length、下标索引,但是他们也有自己的属性,例如item,另外NodeList最大的特点就是时效性(live)。

NodeList的时效性

我们来看下面的代码:



*   index0
*   index1
*   index2
*   index3
*   index4

javascript代码如下:


var myUl = document.getElementById('nodelist');
var lis = myUl.getElementsByTagName('li');

lis是一个NodeList集合,具有时效性,所谓的时效性就是我们在修改li的同时,会反映到lis上来,这与array是不同的,例如我们把第一个li插入到ul的底部,那么lis也会发生相应的变化:


//把第一个li插入的ul的底部
myUl.appendChild(myUl.getElementsByTagName('li').item(0));
console.log(lis[0]);//输出的是原来ul的第二个li

所以我们应该在写代码的时候注意NodeList的时效性,不然就会犯一些错误,

IE6下javascript不能隐藏select标签的bug

昨天做了一个简单的项目,要求有三级联动的select菜单,可是伤不起的IE6下就出现了不能隐藏select的bug,之前我也介绍过IE6下select层高的问题,可以通过隐藏select或者使用iframe遮挡的方式来解决,今天的bug不同以前,大家如果在用js控制select显示隐藏的时候可能会经常遇到,调试一下午终于找到了解决的方案,特此记录一下。

IE6不能隐藏select重现代码

建立两个关联的select,通过javascript控制第一个select 发生变化后,第二个select根据第一个value重新添加options,如果为空则隐藏第二个select(示例中判断除第一个之外都隐藏),则由第一个select的第三个value切换到第二个value则第二个select就不会隐藏。
具体效果见下面的实例:

IE6 select隐藏bug

IE6下不能隐藏select标签解决方案

  1. 可以通过先设置select为显示,后设置为none的方式
  2. 通过给select添加class来控制显示
    具体方法,见示例代码源码注释的地方。

[转]利用跨域资源共享(CORS)实现ajax跨域调用

前几天看了一篇E文说部署CORS文章,CORS是一中跨域的方式,于是上网找了下Nicholas C. Zakas 的文章《Cross-domain Ajax with Cross-Origin Resource Sharing》,并且找到了中文的翻译,感觉不错,转来分享之。

几年前,网站开发者都因为ajax的同源策略而撞了南墙。当我们惊叹于XMLHttpRequest对象跨浏览器支持所带来的巨大进步时,我们很快发现没有一个方法可以使我们用JavaScript实现请求跨域访问,对此我们哀叹不已。每个人在他们自己的网站上建立代理(which was the onset of a new host of open redirect problems)来摆脱这种限制。虽然开发者利用服务器代理和其它技巧避开了这种限制,而在社区的抗议者允许ajax在本地跨域调用。许多人还没意识到当前几乎所有的浏览器(Internet Explorer 8+, Firefox 3.5+, Safari 4+和 Chrome)都可通过名为Cross-Origin Resource Sharing的协议支持ajax跨域调用。

跨域资源共享(CORS)

Cross-Origin Resource Sharing (CORS)是W3c工作草案,它定义了在跨域访问资源时浏览器和服务器之间如何通信。CORS背后的基本思想是使用自定义的HTTP头部允许浏览器和服务器相互了解对方,从而决定请求或响应成功与否。

对一个简单的请求,没有自定义头部,要么使用GET,要么使用POST,它的主体是text/plain,请求用一个名叫Orgin的额外的头部发送。Origin头部包含请求页面的头部(协议,域名,端口),这样服务器可以很容易的决定它是否应该提供响应。

Origin: http://www.nczonline.net

如果服务器确定请求被通过,它将发送一个Access-Control-Allow-Origin头部响应发送请求的同一个源,如果是一个公共资源,则返回“*”。如:

Access-Control-Allow-Origin: http://www.nczonline.net

使用javascript将XML解析为JSON

今天看了David Walsh一篇把XML格式转换为JSON格式的文章,感觉不错,简单的转载了过来。
下面是神奇的XML转JSON的javascript代码:


    // Changes XML to JSON
function xmlToJson(xml) {

    // Create the return object
    var obj = {};

    if (xml.nodeType == 1) { // element
        // do attributes
        if (xml.attributes.length > 0) {
        obj["@attributes"] = {};
            for (var j = 0; j < xml.attributes.length; j++) {
                var attribute = xml.attributes.item(j);
                obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
            }
        }
    } else if (xml.nodeType == 3) { // text
        obj = xml.nodeValue;
    }

    // do children
    if (xml.hasChildNodes()) {
        for(var i = 0; i < xml.childNodes.length; i++) {
            var item = xml.childNodes.item(i);
            var nodeName = item.nodeName;
            if (typeof(obj[nodeName]) == "undefined") {
                obj[nodeName] = xmlToJson(item);
            } else {
                if (typeof(obj[nodeName].length) == "undefined") {
                    var old = obj[nodeName];
                    obj[nodeName] = [];
                    obj[nodeName].push(old);
                }
                obj[nodeName].push(xmlToJson(item));
            }
        }
    }
    return obj;
};

一道js正则笔试题

写在前面

终于找到工作了,现在在新浪微博工作,谢谢这段时间来帮我找工作的朋友。北京的生活的确压力很大,最起码心累,自己慢慢适应就好了。

不得不提的是拆那ZF的办事效率,我回家转户口,青岛老家来回跑了三四天,竟然还是没有给我搞定,最后说青岛户口已经起出来了,老家还要等十五天之后才可以看到结果,然后才能给我落户口!难道ZF的技术就那么差劲啊!数据库还是不统一的,还是故意要老百姓多跑几次,以调动内需?哎……

一道javascript正则笔试题目

在笔试的时候碰到了一道正则的题目,自己不会,后来查了很多资料也没找到,经过在Qwrap的QQ群里提问终于明白了是什么回事,特地记录一下。原题大致如下:

var a = new RegExp("123","g");
var b = "abc#123";

console.log(a.test(b));//true
console.log(a.test(b));//false
console.log(a.test(b));//true
console.log(a.test(b));//false

问为什么会输出truefalsetruefalse

最短的DOMReady代码

自己的js框架YQ还没有添加DOMReady代码,今天看到国外js牛人Dustin Diaz的文章,得到了一份最短的DOMReady代码,分享出来:


function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}

Dustin Diaz放弃了使用IE的document.documentElement.doScroll('left')(这也是多数框架的方法,详细介绍)。使用了setTimeout来定时检测document.readyStatedocument.readyState有以下五种状态:

WinHttp.WinHttpRequest.5.1—可以用作抓取的msxml 4.0底层对象

前些日子在博客园上看到的一篇文章(现在搜索不到了,尽转载的),介绍了下WinHttp.WinHttpRequest.5.1。自己也查了一些资料,写了个vbscript脚本,来添加新浪微博好友。WinHttp.WinHttpRequest的介绍可以去微软官方查看,也有个介绍的网站:http://www.neilstuff.com/winhttp/。感兴趣的可以移步去围观一下。

简单看一下我改的博客园文章的代码,用于新浪微博自动添加好友,因为是前些日子写的。申请离职之后,害怕自己的以前的一些代码丢失,特发到网上来备案一下。简单解释在代码中,加上之前的php的curl函数,WinHttp.WinHttpRequest.5.1应该对以后一些研究会有帮助。而且WinHttp.WinHttpRequest也可以设置refer,cookie,user-agent,proxy……,关键是他可以在cmd里面跑,感觉比较酷(当然php也可以做到,但是不熟悉php的可以用js写出来代替curl)。不废话了,直接上代码。


function RemoteCall(method, url, param, header){  
    var obj = new ActiveXObject("WinHttp.WinHttpRequest.5.1");  
    obj.Open(method||"GET", url, false);  
    obj.Option(4) = 13056;  
    obj.Option(6) = false;  
    obj.setRequestHeader("Cookie", "string");//先设置一个cookie,防止出错,见官方文档
    obj.setRequestHeader("Cookie","你的新浪微博cookie");
    obj.setRequestHeader("Host","t.sina.com.cn");
    obj.setRequestHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    obj.setRequestHeader("User-Agent","Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 QQDownload/1.7 FirePHP/0.5");
    obj.Send(param);  
    return obj;  
}
function post(url,param){
    var obj = new ActiveXObject("WinHttp.WinHttpRequest.5.1");  
    obj.Open("POST", url, false);  
    obj.Option(4) = 13056;  
    obj.Option(6) = false;  
    obj.setRequestHeader("Cookie", "string");
    obj.setRequestHeader("Cookie","你的新浪微博cookie");
    obj.setRequestHeader("Host","t.sina.com.cn");
    obj.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
    obj.setRequestHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    obj.setRequestHeader("User-Agent","Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 QQDownload/1.7 FirePHP/0.5");
    obj.Send(param);  
    return obj; 
}

html5+css3版的爱墙上了

趁着中午休息,发篇文章。不管怎样,从周末开始折腾重构爱墙昨天上了(地址:http://lovewall.js8.in,老版:http://love.js8.in),昨天由于局域网的DNS没有更新,所以也没访问,今天看了下还算比较正常,就是空间速度有点挫,国外的,你懂的!

新版爱墙程序变化:

  1. 程序全部重构,php采用公司同事开发的rareMVC框架
  2. 前端重写,采用html5+css3,所以推荐使用chrome或者FF3.6+体验
  3. javascript代码全部重写,采用了自己的简单框架YQ(暂命名
  4. 添加表情功能
    为啥重构爱墙?:

  5. 熟悉php面向对象开发,MVC开发

  6. 实践html5+css3
  7. 测试自己的框架YQ(源码
  8. 打发周末时间
    这个版本的爱墙程序兼容IE6+,chrome,Firefox,主要是练手用的,不再继续维护开发。此程序前端代码全部未压缩处理,欢迎观摩指导

ps:今天看了下浏览记录,发现谷歌搜索“jsonp”我的一篇文章竟然排了第一,甚是欣慰~O(∩_∩)O哈哈~

转变代码思路:js浏览器判断方法

“变则通,通则达”,在coding的时候也要做到,有时候思路往往太过于局限性,对浏览器判断方法的实例,来说说代码思路的转变。

关于javascript对浏览器的判断,很早之前我写过一篇文章《js判断浏览器的函数,可区分chrome,safari\》。

YQ框架中也是采用的这个方法,可是后来想到了有位网友说判断火狐的版本号会错误,这是因为火狐的version的判断走了正则,而没有考虑到firefox的,其实不止firefox有这个bug。

首先来看看火狐的navigator.userAgent:
这个是我的firefox(3.6.15,却显示3.6.8,不知何解,查看关于也是这个问题:版本不统一)

Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8 QQDownload/1.7

根据正则的写法,火狐的版本号应该这样写/Firefox[\/]([\w.]+)/
而safari的确是类似的:

……Version/3.1 Safari/525.13

其中Version为实际的版本号,也是我们常称呼的版本号。

琢磨

开始写js判断浏览器的,跟jQuery的$.browser一样,可是版本号会出现问题,只不过是加了个chrome判断而已。开始想解决方法,初步想得是通过一个正则对象把浏览器的名称和版本号统一匹配出来,正则对象设置如下:

var browserRegExp = {
    ie:/(msie)[ ]([\w.]+)/,
    firefox:/(firefox)[ |\/]([\w.]+)/,
    chrome:/(chrome)[ |\/]([\w.]+)/,
    safari:/version[ |\/]([\w.]+)[ ](safari)/,
    opera:/(opera)[ |\/]([\w.]+)/
}

自己写的一个轻量级javascript框架的设计模式

公司一直使用jQuery框架,一些小的项目还是觉得jQuery框架太过于强大了,于是自己周末有空琢磨着写个自己的框架。谈到js的设计模式,不得不说说js的类继承机制,javascript不同于PHP可以轻松的实现类继承,不过javascript的类继承方法还是有的,常见的有构建函数、原型扩展、综合……,也有一些专门写类的函数,例如jQuery的作者有个类继承函数。关于类继承写法可以简单看看这篇文章

我自己写的框架也不知道叫什么名字,刚开始写的时候随手写了个W(姓拼音,之前写过jQuery弹出框插件wBox),现在写这篇文章重新整理了一下思想,换了YQ(名字拼音,你懂的~)。

核心代码

框架设计的时候尽量做到了支持链式写法,也就是返回this,可以$(selector).handler1().handler2()……无限写下去,只要不是有返回值的就可以继续。包括了event,dom,css,还有fadeIn,fadeOut动画(因为再重构爱墙[html5+css3]版,所有顺手加上了这个功能)。如果配合sizzle选择器就更牛了!

下面说说框架的核心代码,等完善了之后跟新版html5爱墙一起放出,主要的代码如下: