【问题标题】:Select tags that starts with "x-" in jQuery在jQuery中选择以“x-”开头的标签
【发布时间】:2013-06-13 00:13:21
【问题描述】:

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

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

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

【问题讨论】:

  • 这首先有效吗? &lt;x-map&gt;&lt;/x-map&gt;
  • 其实是一种声明自定义元素的新方式,就像x-tags.orgpolymer-project.org项目
  • @Scott Selby: :contains() 用于文本,而不是标签名称。
  • 我倾向于没有简单的开箱即用解决方案,因为 jQuery element selector 最终会调用 getElementsByTagName(),它不会使用通配符。
  • 这不是有效的 HTML 并检查 x-tags.org 本身是否无效。 validator.w3.org/…

标签: javascript jquery jquery-selectors x-tag


【解决方案1】:

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

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

Working fiddle

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

更新

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

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

jsperf test

更新 2:

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

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

jsperf test

【讨论】:

  • 我喜欢它,可能有更好的方法来改进它,但现在可以帮助我..
  • 好更新。我已经在我的答案中添加了 cmets。谢谢你提出来。我赞成你的回答。
  • 不过要小心这些测试,因为它们不是很好的例子。在真正的整页中,其他元素与您想要的元素的比例不太可能相同。有趣的是看到 document.all。我还以为是老东西了。
  • @MohamedMeligy 谢谢,不过我会小心测试的。 :)
【解决方案2】:

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

示例:

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

完整示例:

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

注意事项:(已更新,见 cmets)

如果您想知道为什么我使用这种方式来检查标签名称,请参阅:
JavaScript: case-insensitive search
并查看 cmets。

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

在 cmets 中,您会发现它并没有更快的证据。尽管我相信这适用于非常简单的文档,其中创建 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。

【讨论】:

  • 很好,很好看。你提到了性能;出于好奇,您如何衡量性能?使用 chrome 开发工具或 jsperf 进行分析?
  • 根据几乎所有 jQuery 性能文章(由许多 JSPerf 测试证明),本机浏览器选择器是最快的。对于伪元素(更新版本)和浏览器本身不支持的几乎所有选择器(非 CSS),JS(jQuery)必须获取范围内的所有元素(这就是限制范围父级的原因)并测试每个元素而不是要求浏览器直接返回它们。
  • 这里还有一些关于它如何工作的好信息wordsbyf.at/2011/11/23/selectors-selectoring,当然还有官方的jQuery性能学习页面learn.jquery.com/performance/optimize-selectors
  • 哇!!我曾经学习和编写编码,大部分时间我都在努力寻找优化的解决方案。更多的东西要学,还有很长的路要走。感谢您花时间指导我:)
【解决方案3】:

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

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

你会得到所有以x-开头的标签

【讨论】:

  • 我也想过这个解决方案..但问题是您每次都需要添加一个属性,以“x-”开头的标签名称背后的想法是帮助查询而不是允许所有类型没有任何模式的自定义元素
  • @mateusmaso:题外话,但我想知道是否有人提出过这样的想法。我们已经有了一种看起来像 HTML 但现在提供开箱即用的命名空间的标记语言已有 十年 了;它被称为 XML,它在 HTML 中表现为 XHTML。再说一次,jQuery doesn't support XML namespaces anyway,让这一点变得毫无意义。
【解决方案4】:

自定义 jquery 选择器

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

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

【讨论】:

  • 很好的表达方式:)
【解决方案5】:

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

$('x-tab, x-map, x-footer')

【讨论】:

  • 是的,除了指定每个单独的元素名称,真的没有其他方法了。
【解决方案6】:

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

我的意思是,

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-']") 或相同的操作,它会相当快。

【讨论】:

    【解决方案7】:

    看看这是否有效!

    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;
    }
    

    【讨论】:

      【解决方案8】:

      Demo Fiddle

      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');
          }
      }
      

      【讨论】:

        【解决方案9】:

        试试这个

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

        基本上 jQuery 选择器的工作方式类似于 CSS 选择器。 Read jQuery selector API here.

        【讨论】:

        • 如果您自己阅读过它,您就会意识到这实际上行不通。
        猜你喜欢
        • 2013-08-24
        • 2016-05-22
        • 2021-06-29
        • 2017-02-03
        • 1970-01-01
        • 2021-12-31
        • 2020-12-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多