比较两组匹配的元素

时间:2013-06-19 15:59:56

标签: jquery

我需要比较不同的选择器是否返回相同匹配的元素集。

我来到这个简单的解决方案,一个小插件:

;(function ($) {
    $.fn.isEqual = function ($selector) {
       return this.add().get().join() === $selector.add().get().join()
    }
})(jQuery);


//e.g of usages: if($('div').isEqual($('#mydiv1,#mydiv2'))
//if($(':checkbox').isEqual($('input[type=checkbox].myclass'))
//if($('div').parents().isEqual($('body div').parents()) etc ...

现在我觉得我错过了一些东西,因为我找到的所有其他解决方案看起来都非常精细,就像这个似乎是特权的那个:

$.fn.sequenceEqual = function(compareTo) {
  if (!compareTo || !compareTo.length || this.length !== compareTo.length) {
    return false;
  }
  for (var i = 0, length = this.length; i < length; i++) {
    if (this[i] !== compareTo[i]) 
      return false;
    }
  }
  return true;
} 

那么,使用$ .isEqual插件会有什么不利之处?

5 个答案:

答案 0 :(得分:5)

Array join()将数组字符串化,因此您依赖于jQuery元素集的字符串化版本。 DOM元素字符串化为类似[object HTMLDivElement]的字符串,所以实际上你只是比较每个jQuery对象中元素的大小,顺序和类型。

例如,

$("div:first").isEqual($("div:last"))

总是如此,因为两个选择器都捕获一个<div>(即它们都串联成“[object HTMLDivElement]”),但这个断言实际上应该是真的很少。

即使某些浏览器 提供了一种在字符串表示形式中唯一标识元素的方法,toString的{​​{1}}行为也未被任何标准指定,因此您冒着跨浏览器兼容性的风险。 (但是,没有浏览器会这样做,因此您的代码无法在任何浏览器中正常运行。)

答案 1 :(得分:1)

正如你所说我需要比较不同的选择器是否返回相同匹配的元素集

这个简化的插件怎么样 -

;(function ($) {
    $.fn.isEqual = function ($selector) {
       return this.is($selector);
    }
})(jQuery);

答案 2 :(得分:1)

.isEqual.sequenceEqual不同的比较级别。

.isEqual - 比较返回选择器的el.toString。含义<div id="test"></div><div id="test1"></div>相同,$('#test').isEqual('#test1')将返回true,因为比较基于toString [object HTMLDivElement]

.sequenceEqual进行节点比较,基本上遍历所有元素并逐一进行比较。

以上假设你的.add错误存在。

DEMO: http://jsfiddle.net/2QYgp/

(function ($) {
    $.fn.isEqual = function ($selector) {
           return this.get().join() === $($selector).get().join()
    }
})(jQuery);

$(function () {
    alert($('#test1').isEqual('#test'));
});

答案 3 :(得分:1)

isEqual假设DOMNode.toString()生成一些唯一标识DOM节点的字符串。这是错误的假设。 W3C DOM规范未指定AFAIR DOMElement.toString(),因此您无法依赖其结果 - 它们在不同的UA中会有所不同。

如果任务是测试相等性,那么sequenceEqual是正确的,而不是相似性。

答案 4 :(得分:0)

开头......

if($('div').isEqual('#mydiv1,#mydiv2'))

给出错误,sequenceEqual给出“false”