【问题标题】:Return all elements for which any attribute starts with something返回任何属性以某事物开头的所有元素
【发布时间】:2019-05-01 07:34:41
【问题描述】:

我知道[name^="value"]selector,但是是否有类似的选择器(或技术)可以查询以给定值开头的所有属性?

我正在寻找类似$("[*^='http://www.something.com']")(不存在)的东西。

它将匹配包含至少一个属性值以http://www.something.com 开头的所有元素。

说:

<img src="http://www.something.com/image.jpg" />
<a href="http://www.something.com">Something</a>
<link rel="stylesheet" href="http://www.something.com/css/style.css" type="text/css">

属性名称可以是任何名称,而不仅仅是srchref,甚至是非标准属性。

有已知的方法吗?

【问题讨论】:

  • 这需要整个 DOM 被迭代,我认为每个元素的属性集合都被迭代。如果您愿意,我可以用 JavaScript 编写它,然后您可以将它作为选择器扩展添加到 jQuery?不过,它不会表现出色。
  • 为什么你需要做这样的事情?当然有更好的解决方案。
  • 这样的东西永远不应该存在,它没有没有用例。您有 两个 整个属性可供选择,并且您只对三种类型的标签感兴趣,因此不要通过检查每个元素的每个属性来粗暴化您的 DOM,只需针对属性编写三个查询你真的关心并完成它:img[src$=http://whatever],link[href$=http://whatever],a[href$=http://whatever]。你需要想出一个更好的现实世界的理由来检查每个元素的每个属性,没有理由永远这样做。
  • danronmoon,已修复。零和粉碎,谢谢!其他人,我有我的理由和用例,data-* 等属性有无限可能,甚至是不合格的属性。性能不是问题,我喜欢粗暴化 DOM :D。

标签: javascript jquery


【解决方案1】:

我将其他答案中的一些想法汇总并编写了一个自定义选择器。

选择器

$.expr[':'].hasAttrStartingWithValue = function (obj, index, meta) {

    var startsWithAttrValue = false;
    var value = meta[3];

    for (var i = 0; i < obj.attributes.length; i++) {
        var attr = obj.attributes[i];
        // attr.value starts with value
        if (attr.specified && attr.value.lastIndexOf(value, 0) === 0) {
            startsWithAttrValue = true;
            break;
        }
    }

    return startsWithAttrValue;
};

它没有经过适当的交叉浏览和正确性测试,我确信它可以进一步优化,但它似乎在 IE 11、FF 24 和 Chrome 32 上运行良好。

用法

// Logs every occurrence of a value in any attribute of the page
$(":hasAttrStartingWithValue('http://www.something.com')").each(function (i, e) {
    console.log(i + " - " + e.outerHTML);
});

// Matches only children of test
$("#test :hasAttrStartingWithValue('http://www.something.com')")
   .css('background-color', 'red'); 

Working Fiddle.

【讨论】:

    【解决方案2】:
    function strstr (haystack, needle, bool) {
      var pos = 0;
    
      haystack += '';
      pos = haystack.indexOf(needle);
      if (pos == -1) {
        return false;
      } else {
        if (bool) {
          return haystack.substr(0, pos);
        } else {
          return haystack.slice(pos);
        }
      }
    }
        $( document ).ready(function(){
        $('*').each(function() {
          $.each(this.attributes, function() {
            // this.attributes is not a plain object, but an array
            // of attribute nodes, which contain both the name and value
            if(this.specified) {
              if( strstr(this.value,'http://') )
                alert(this.name+'+'+this.value);
            }
          });
        });
    
        });
    

    警报所有属性和值...
    自定义此代码...
    jsfiddle

    【讨论】:

    • 感谢您回答 Eskandari,我完全忘记了 specified 属性。
    • 哦!没问题! Jquery 是很棒的语言 :)
    • i load() &lt;form&gt; 通过 Ajax 但 submit() 事件或 on('submit',...) 不适用于此。但它在没有由 ajax 加载时工作!!!你知道这是什么问题???谢谢!
    • Eskandari,问个问题把链接发给我,我一定会看的。
    【解决方案3】:

    如果你想为 img、a 和链接标签做这件事,那么你可以这样做:

    var ref = '"http://www.something.com"';
    var elems = [].slice.call(document.querySelectorAll('img[src='+ref+'], a[href='+ref+'], link[href='+ref+']'));
    //do something with the elems array
    

    如果你想走另一条路……

    JS Fiddle of Working Abomination in Vanilla JS

    让我伤心的代码(查询眼前的一切、循环中的循环、循环中的正则表达式等):

    var rx = /(^http:\/\/www.something.com)/;
    var loopAgain = function () {
        for (var j = 0, leng = attrs.length; j < leng; j++) {
            if (rx.test(attrs[j].value)) {
                return true;
            }
            return false;
        }
    };
    var allTheThings = [].slice.call(document.querySelectorAll('*'));
    for (var i = 0, len = allTheThings.length; i < len; i++) {
        var attrs = allTheThings[i].attributes;
        if (loopAgain()) {
            console.log(allTheThings[i]);
        }
    }
    

    【讨论】:

    • 谢谢 rjreed,你的“可憎”当然是受欢迎的。我想你的start with 的正则表达式实现也将能够获得更好的性能,如果我能找到一种聪明的方法来只创建一次正则表达式并将它保持在每次调用选择器的范围内,我将更新我的答案更像你的:)。
    猜你喜欢
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 2016-09-12
    • 2013-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多