html段落循环,html片段去重,单层循环能搞定么?

更新:以前的答案有问题,留着鞭尸吧……

Sizzle的去重流程可以参考:

用compareDocumentPosition或其shim来判断节点关系,sort你的DOM Array

然后判断Array中前后两个节点是否全等,全等则将相关的编号push入duplicate数组

逆向遍历duplicate数组,把DOM Array里面的重复节点全部都splice掉

Sizzle.uniqueSort = function( results ) {

var elem,

duplicates = [],

j = 0,

i = 0;

results.sort( sortOrder );

while ( (elem = results[i++]) ) {

if ( elem === results[ i ] ) {

j = duplicates.push( i );

}

}

while ( j-- ) {

results.splice( duplicates[ j ], 1 );

}

return results;

};

源码见这里

如果compareDocumentPosition被浏览器支持,那么去重循环是单层的,反之则需要用到二重循环的内层来shim compareDocumentPosition,判断节点关系,见这里

最好的情况下,Sizzle方案的消耗为:sort大致为O(nlogn) + 一重去重循环O(n) + DOM总开销(未知)。

有时间了跑一个benchmark。

不过compareDocumentPosition作为DOM Level 3的内容,它的浏览器兼容,据我点开这里测试,是这样的结果:

ie6 ie7 ie8 ie9 chrome firefox

× × × √ √ √

在支持它的浏览器(IE9+)里,也支持querySelectorAll(IE8+,见这里),我们自己做selector的意义不大;

反之,不支持它的浏览器,我们需要自己实现compareDocumentPosition,这样就多了一层循环,Sizzle方案里的双层循环去重恐怕不可避免。

当然,如果我们用一个唯一性ID标识所有的DOM节点,倒是可以单层循环去重。只不过这个方案的开销可不比Sizzle的方案小,还需要跟踪所有的DOM新增节点。

下面是尸体:

回到需求。

按照选择符描述去正向匹配是有这种过滤、父子层级的问题。这就是为什么CSS选择器的浏览器实现,以及高效的sizzle走了相反的路子:反向匹配。

这样的话,对于选择器div span,我们先找到所有的span,然后判断它的祖先层级是不是div。

你看,需要做去重吗?

想了一下,在这个问题上,读取的顺序不是太重要,对于这样的文档结构还是有重复的问题:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值