10

如何选择以"x-"标签名称开头的节点,这是一个层次结构 DOM 树示例:

<div>
  <x-tab>
    <div></div>
    <div>
      <x-map></x-map>
    </div>
  </x-tab>
</div>
<x-footer></x-footer>

jQuery 不允许我查询$('x-*'),有什么方法可以实现吗?

4

9 回答 9

7

下面的工作正常。虽然我不确定我使用正则表达式时的性能。

$('body *').filter(function(){
    return /^x-/i.test(this.nodeName);
}).each(function(){
    console.log(this.nodeName);
});

工作小提琴

PS:在上面的示例中,我将body标签视为父元素。

更新

检查 Mohamed Meligy 的帖子后,在这种情况下,似乎正则表达式比字符串操作更快。如果我们使用它可能会变得更快(或相同)find。像这样的东西:

$('body').find('*').filter(function(){
    return /^x-/i.test(this.nodeName);
}).each(function(){
    console.log(this.nodeName);
});

jsperf 测试

更新 2:

如果您想在文档中搜索,那么您可以执行以下最快的操作:

$(Array.prototype.slice.call(document.all)).filter(function () {
    return /^x-/i.test(this.nodeName);
}).each(function(){
    console.log(this.nodeName);
});

jsperf 测试

于 2013-06-17T05:49:51.470 回答
6

没有本地方法可以做到这一点,它的性能最差,所以,自己做吧。

例子:

var results = $("div").find("*").filter(function(){
    return /^x\-/i.test(this.nodeName);
});

完整示例:

http://jsfiddle.net/6b8YY/3/

注:(已更新,见评论)

如果您想知道为什么我使用这种方式来检查标签名称,请参阅:
JavaScript:不区分大小写的搜索
并查看注释。

此外,如果您想知道该find方法而不是添加到选择器,因为选择器是从右而不是从左匹配的,因此最好将选择器分开。我也可以这样做:
$("*", $("div"))。最好不要只是div添加一个 ID 或其他东西,以便快速匹配父级。

在评论中,您会发现它并没有更快的证据。尽管我相信这适用于非常简单的文档,其中创建 jQuery 对象的成本高于搜索所有 DOM 元素的成本。在实际的页面大小中,情况并非如此。

更新:

我也很喜欢 Teifi 的回答。您可以在一个地方完成它,然后在任何地方重复使用它。例如,让我将我的方式与他的方式混合起来:

// In some shared libraries location:
$.extend($.expr[':'], {
    x : function(e) {
            return /^x\-/i.test(this.nodeName);
    }
});

// Then you can use it like:
$(function(){
    // One way
    var results = $("div").find(":x");

    // But even nicer, you can mix with other selectors
    //    Say you want to get <a> tags directly inside x-* tags inside <section>
    var anchors = $("section :x > a");

    // Another example to show the power, say using a class name with it:
    var highlightedResults = $(":x.highlight");
    // Note I made the CSS class right most to be matched first for speed
});

它具有相同的性能,但更方便的 API。

于 2013-06-17T05:59:25.473 回答
3

它可能效率不高,但如果您没有得到任何答案,请考虑将其作为最后的选择。
尝试向这些标签添加自定义属性。我的意思是当您为例如添加标签时。<x-tag>,为其添加一个自定义属性并为其分配与标签相同的值,因此 html 看起来像<x-tag CustAttr="x-tag">.
现在要获取以 开头的标签x-,您可以使用以下 jQuery 代码:

$("[CustAttr^=x-]")

你会得到所有以x-

于 2013-06-17T05:25:13.870 回答
3

自定义 jquery 选择器

jQuery(function($) {
    $.extend($.expr[':'], {
        X : function(e) {
            return /^x-/i.test(e.tagName);
        }
    });
});

比,使用$(":X")$("*:X")来选择您的节点。

于 2013-06-17T06:35:32.797 回答
2

虽然这不能直接回答问题,但它可以提供解决方案,但通过在选择器中“定义”标签,您可以获得所有类型?

$('x-tab, x-map, x-footer')
于 2013-06-17T05:42:57.377 回答
1

解决方法:如果你不止一次想要这个东西,添加一个基于标签的类可能会更有效 - 你在开始时只做一次,然后你用简单的方式过滤标签。

我的意思是,

function addTagMarks() {
    // call when the document is ready, or when you have new tags

    var prefix = "tag--"; // choose a prefix that avoids collision
    var newbies = $("*").not("[class^='"+prefix+"']"); // skip what's done already

    newbies.each(function() {
        var tagName = $(this).prop("tagName").toLowerCase();
        $(this).addClass(prefix + tagName);
    });

}

在此之后,您可以使用 querySelectorAll 执行 $("[class^='tag--x-']") 或相同的操作,它会相当快。

于 2017-10-31T09:53:26.223 回答
0

看看这是否有效!

function getXNodes() {
  var regex = /x-/, i = 0, totalnodes = [];
  while (i !== document.all.length) {
    if (regex.test(document.all[i].nodeName)) {
      totalnodes.push(document.all[i]);
    }
    i++;
  }
  return totalnodes;
}
于 2013-06-17T05:30:51.520 回答
0

演示小提琴

var i=0;
for(i=0; i< document.all.length; i++){
    if(document.all[i].nodeName.toLowerCase().indexOf('x-') !== -1){
        $(document.all[i].nodeName.toLowerCase()).addClass('test');
    }
}
于 2013-06-17T05:57:33.763 回答
-4

试试这个

var test = $('[x-]');
if(test)
    alert('eureka!');

基本上 jQuery 选择器就像 CSS 选择器一样工作。 在此处阅读 jQuery 选择器 API。

于 2013-06-17T05:20:39.540 回答