Actually,simplicity is not simple

速记: jQuery两DOM比较

今天在写基于jQuery的一项目时遇到的问题,先看代码:

var a = $('#sR_Tab');
var b = $('#sR_Tab');
console.log(a == b);   // return false

看到测试返回的值第一时间我感到很差异,但细想下后就明白了,用jQuery有几年了,居然到现在才注意到这问题,失败啊!

在这也给自己理一理吧,再让自己记牢点。

看到上面测试如果还不能想明白的可以测试以下代码:

var a = $('#sR_Tab');
console.log(typeof a);  // return object

结果返回说是Object类型,实际上a是个Array类型的Object,在JS类型中没有这种说法,但切能很让我们很清楚的了解这变量的真正类型,谁叫JS的类型总是含糊不清的。

明白上面的a是个Array类型的Object后就能很好的解释为什么a != b了。在JS的变量中,Array、Object类型的变量其值是指向数据的指针,而非数据本身。而jQuery的$()函数是会返回一个全新的Array类型的Object。所以虽然a、b变量的值是指向不同空间的地址,其值自然不同。

那要如何才能返回真正的比较结果呢?其实jQuery中的$()函数返回的是所选DOM的数组,所以只要得到真正DOM的引用进行比较就能得到我们真正要的比较结果,写法也很简单:

var a = $('#sR_Tab');
var b = $('#sR_Tab');
console.log(a[0] == b[0]);   // return true

呵呵,就这么简单。只是到现在才注意到两jQuery对象比较返回的结果是false让我很郁闷。真郁闷!

HTML的历史

HTML是Web统一语言,这些容纳在尖括号里的简单标签,构成了如今的Web,1991年,Tim Berners-Lee编写了一份叫做“HTML标签”的文档,里面包含了大约20个用来标记网页的HTML标签。他直接借用SGML的标记格式,也就是 后来我们看到的HTML标记的格式。本文讲述了HTML这门Web标记语言的发展简史。

从IETF到W3C:HTML4之路

HTML1并不曾存在,HTML的第一个官方版本就是由IETF(互联网工程任务组)推出的HTML2.0。问世之前,这个版本中的很多细则已经被 实现,比如,1994年的Mosaic浏览器已经实现了在文档中嵌入图片的方法,后来HTML2.0便吸纳了img这个标签。

后来,W3C取代IETF的角色,成为HTML的标准组织,1990年代的后半页,HTML的版本被频繁修改,直到1999年的HTML4.01, 至此,HTML到达了它的第一个拐点。

XHTML1:XML风格的HTML

HTML在HTML4.01之后的第一个修订版本就是XHTML1.0,其中X代表“eXtensible”,扩展,当然也有人将之解读为 “eXtreme”,极端。XHTML1.0是基于HTML4.01的,并没有引入任何新标签或属性,唯一的区别是语法,HTML对语法比较随便,而 XHTML则要求XML般的严格语法。

使用严格的语法规范并非坏事,要求开发者使用单一的代码风格,比如,HTML4.01允许你使用大写或小写字母标识标记元素和属性,XHTML则只 允许小写字母。XHTML1.0的推出刚好碰上了CSS的崛起,Web开发设计者们开始意识到Web标准问题,基于XHTML的严格语法规范被视为编写 HTML代码的最佳实践。

W3C推出XHTML1.1

如果说XHTML1.0是XML风格的HTML,XHTML1.1则是货真价实的XML。这意味着XHTML1.1无法使用 text/htmlmime-type直接输出,然而,如果Web开发者使用XMLmime-type,则当时的主流浏览器,IE则压根不支持。看上 去,W3C似乎正在与当时的Web脱节。

出力不讨好的XHTML2

对W3C而言,到了HTML4已经是功德圆满,他们的下一步工作是XHTML2,希望将Web带向XML的光明未来。虽然XHTML2听上去和 XHTML1类似,它们却有很多差别,XHTML2不向前兼容,甚至不兼容之前的HTML。它是一种全新的语言,赤条条来去无牵挂。这实在是一场灾难。

WHATWG:与W3C决裂

W3C闭门造车的作风引起了一些人的不满,来自Opera,Apple,以及Mozilla的代表开始表达反对声音。2004年,Opera的 Ian Hickson提议在HTML基础上进行扩展以适应新的Web应用,该提议遭到W3C的拒绝。于是,他们自发组织成立了超文本应用技术工作组,就是 WHATWG。

从WebApps1.0到HTML5

从一开始,WHATWG就和W3C走不同的路线,W3C对问题的讨论是集体投票,而WHATWG则由主笔IanHickson定度。表面上 看,W3C更民主,然而事实上,各种内部纷争会使一些决议限于泥潭,在WHATWG,事情的进展会更容易,不过,主笔的权力并非无限大,他们的委员会可以 对那些过于偏执的主笔进行弹劾。

一开始,WHATWG的主要工作包括两部分,Web Forms 2.0和Web Apps 1.0,它们都是HTML的扩展,后来,他们合并到一起成为现在的HTML5规范。

在WHATWG致力于HTML5的同时,W3C继续他们的XHTML2.0,然而,他们慢慢地陷入困境。

2006年10月,Web之父Tim Berners-Lee发表了一篇博客文章,表示,从HTML走向XML的路是行不通的,几个月后,W3C组建了一个新的HTML工作组,他们非常明智地 选择了WHATWG的成果作为基础。这一转变带来一些困惑,W3C同时进行这两套规范,XHTML2和HTML5(注意,W3C的HTTML5在5之前有 个空格,而WHATWG的HTML5则没有空格),而WHATWG也在进行着同样的工作。

XHTML已死:XHTML语法永存

这一混乱局面到了2009年开始变得清晰,W3C宣布终止XHTML2的工作,这是一份关于XHTML2的迟到的讣告。这一消息被那些XML的反对 者视为珍宝,他们借此嘲笑那些使用XHTML1规范的人,然而他们似乎忘记了,XHTML1和XHTML2是截然不同的东西。于此同时,XHTML1规范 的制定者担心,XHTML1中的严格语法规范会被HTML5弃用,这种担心后来证明是多余的,HTML5既支持松散语法,也支持XHTML1般的严格语 法。

HTML5路线图

HTML5的现状是,它不再象以前那样让人困惑,然而仍不够明朗。有两个组织在同时制定它的规范,这两个组织有着完全不同的行事风格,WHATWG 是先买后尝,W3C是先尝后买,他们形成了一个不太靠谱的联姻,最终人们必将面临一个HTML5还是HTML5的问题。

更让开发者困惑的是,他们什么时候才可以试水HTML5。

在一次访谈中,Ian Hickson提到了2022,表示要到那时HTML5才会形成"推荐标准",此话一出,立刻招来Web设计者们的愤怒,尽管他们不知道推荐标准时什么意 思,但他们明白,2022已经是猴年马月的事了。

这还不算,更重要的是,这个推荐标准涉及两套规范,考虑到HTML5标准的规模,这个日期还是太乐观了,毕竟,各大浏览器以往对既有标准的兼容并不 遂人意,想当初,IE花了10年才接纳abbr这个标签。

2012年,HTML5会被接纳为候选标准,这将是HTML5真正开始发力的日子。对Web开发设计者来说,这并不重要,重要的是浏览器的支持,就 像CSS2.1,当有浏览器开始支持这一规范的时候,就有开发设计者在使用了,倘若必须等到所有浏览器都支持才开始入手,恐怕我们现在还在等待中。

HTML5也一样,并不会有一个时间点,宣布HTML5已经准备妥当,相反,我们会先开始使用它的部分功能,HTML5并不是一个从零开始全新的东 西,它是旧的HTML标准的改进,事实上,不管你正在使用的HTML是哪个版本,你已经在使用HTML5了。

用HTML工作几年了,还不太了解HTML的历史,惭愧,信在CB上看到的,转一下吧!

jQuery.contains()函数在Firefox下的'bug'

再来写点有关contains的事情,今天做项目时刚好可以用上contains,只是我的项目是基于jQuery的,就使用jQuery内部的jQuery.contains()函数了,但我发现这函数在Firefox有问题。

先看下测试Demo

$(document).ready(function(){
    alert( $.contains($('div.wrap')[0], $('#fdsfafd')[0]) );
    alert(4322);
    $('h1').click(function(){alert(111);});
});

在Firefox下,如果$('#fdsfafd')[0]不存在会导致整个页面的JS锁死,不再会执行任何代码了。

我现在的解决办法是是保证$.contains()中第二个参数存在,代码如下:

alert( $.contains($('div.wrap')[0], $('#fdsfafd')[0]||$('body')[0]) );

方法我知道很淫荡,但先这样了,没时间去改jQuery的内部实现。

contains()函数使用一例

今天看到的,让我了解了下compareDocumentPosition()contains()函数,以后判断是否在元素上面就有新方法了。其它的也没什么好说,看下Demo吧!

window.onload = function () {
    document.getElementById('dropdown').onmouseover = openMenu;
}

function openMenu(e) {
    var evt = e || window.event;
    var tgt = evt.target || evt.srcElement;
    while (tgt.nodeName !== 'LI') {
        if (tgt.nodeName === 'HTML') {
            return;
        }
        tgt = tgt.parentNode;
    }
    var nested = tgt.getElementsByTagName('ul')[0];
    if (nested) {
        nested.className = 'open';
        tgt.onmouseout = function (e) {
            var evt = e || window.event;
            var related = evt.relatedTarget || evt.toElement;
            if (!nested.contains(related)) {
                nested.className = '';
                tgt.onmouseout = null;
            }
        }
    }
}

/* Bloody Firefox STILL doesn't support contains */

if (window.Node && Node.prototype && !Node.prototype.contains) {
    Node.prototype.contains = function (arg) {
        return !!(this.compareDocumentPosition(arg) & 16)
    }
}