返回所有属性以某些内容开头的元素

4

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

我正在寻找类似于$("[*^='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,甚至包括非标准属性。

有已知的方法来实现这个吗?


7
需要遍历整个DOM,然后遍历每个元素的属性集合。如果您愿意,我可以用JavaScript编写它,然后您可以将其添加为jQuery的选择器扩展?但是它的性能不会很好。 - crush
3
请查看 https://dev59.com/72sy5IYBdhLWcg3wtwMd#8371266 以了解大致想法。 - dsgriffin
2
为什么你需要做这样的事情呢?肯定有更好的解决方案。 - gen_Eric
4
这种东西不应该存在,它没有任何用途。您有两个属性可供选择,但只对三种类型的标记感兴趣,因此不要强制检查每个元素的每个属性来粗暴地处理您的 DOM,而是对您实际关心的属性编写这三个查询,然后就完成了: img[src$=http://whatever], link[href$=http://whatever]a[href$=http://whatever]。您需要为希望检查每个元素的每个属性提供更好的现实世界的理由,因为根本没有必要这样做。 - user229044
3
danronmoon,fixed。null和crush,谢谢!其他人,我有我的理由和用例,可以使用无限的属性,如data-*以及不符合规范的属性。性能不是问题,而且我喜欢折磨DOM :D。 - Anthony Accioly
显示剩余4条评论
3个回答

3

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

选择器

$.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'); 

演示代码


1
如果你想针对img、a和link标签做这件事,你可以像这样做:
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 工作时的 JS Fiddle 令我感到悲伤的代码(查询所有可见内容,循环嵌套,循环中的正则表达式等):
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]);
    }
}

1
感谢rjreed,您的“恶心”的确受欢迎。我猜您的正则表达式实现 start with 也能够在性能上有所提升,如果我能够找到一种聪明的方法只创建一次 RegExp 并使其在每次调用选择器时保持在范围内,我将更新我的答案使其更接近于您的 :)。 - Anthony Accioly

1
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属性。 - Anthony Accioly
哦!没问题!Jquery是一种很棒的语言 :) - Mahmoud.Eskandari
我通过Ajax加载了<form>,但是submit()事件或on('submit',...)对此无效。但是当不通过ajax加载时它可以工作!你知道这是什么问题吗?谢谢! - Mahmoud.Eskandari
Eskandari,请提出问题并发送链接,我一定会查看。 - Anthony Accioly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接