【问题标题】:How to get all HTML attributes which start with something (the attribute names, *not* their values!)如何获取所有以某些东西开头的 HTML 属性(属性名称,*不是*它们的值!)
【发布时间】:2012-04-25 09:56:25
【问题描述】:

我想获取 HTML 页面中包含以某事物开头的属性的所有元素/节点(同样,属性名称以某事物开头,而不是它们的值!)。例如,TinyMCE 倾向于将自定义属性添加到它保存的元素中,例如"mce_style""mce_href""mce_bogus" 等。我想要属性值的 CSS3 选择器之类的东西,[attr^="mce_"]但不适用于值、属性名称

当然,我可以遍历所有 DOM 节点及其属性,并一一检查,但我想知道是否有更有效的方法。

请不要给我 TinyMCE 特定的答案,我很确定有一个标志会阻止 TinyMCE 保存这些属性,但问题是通用的。

【问题讨论】:

  • 我觉得您要么必须遍历每个元素,并查看每个属性。即使document.querySelectorAll() 也没有attribute-name-begins-with 选项。有趣的问题。
  • 我对 TinyMCE 一无所知,但如果有某种方法可以识别具有 any 此类属性的元素,那么您至少可以先将搜索范围缩小到一个子集,然后查看子集的每个属性,这将比查看整个 dom 快得多。也就是说,是否有一些属性将始终添加到您的目标之一?如果是这样,请先查找。
  • @jamietre 是的,就 TinyMCE 而言,您可以假设例如mce_href 将始终应用于 a 元素,因此您可以缩小搜索范围。但正如我在上一句中所说,我不是在寻找特定于 TinyMCE 的答案,我宁愿有一个通用的解决方案,从我目前得到的答案来看,除了遍历所有元素之外别无他法他们的属性。皮蒂。
  • 嗯,是的,但它确实引出了为什么的问题?我的意思是,是否有任何广泛使用的工具会让您陷入这种情况?没有理由编写代码来创建任意命名的元素,而没有其他方法可以识别节点。这有点像问,如何在不使用全文索引的情况下找到数据库中包含一些文本的每条记录?你没有。您使用全文索引。
  • HTML 中的自定义(和无效)属性已被(ab)永久使用,但此链接显示了在 HTML 5 中的有效使用以及具有快速和通用机制来检索这些属性的要点: ejohn.org/blog/html-5-data-attributes 如果你用谷歌搜索“自定义 html 属性”,我相信你会发现更多案例。

标签: javascript dom selector


【解决方案1】:

here's a simple demo 查找包含以mce_ 开头的属性的所有元素。可能需要一些改进。

function getMCE() {
    var el, attr, i, j, arr = [],
        reg = new RegExp('^mce_', 'i'),                //case insensitive mce_ pattern
        els = document.body.getElementsByTagName('*'); //get all tags in body

    for (i = 0; i < els.length; i++) {                 //loop through all tags
        el = els[i]                                    //our current element
        attr = el.attributes;                          //its attributes
        dance: for (j = 0; j < attr.length; j++) {     //loop through all attributes
            if (reg.test(attr[j].name)) {              //if an attribute starts with mce_
                arr.push(el);                          //push to collection
                break dance;                           //break this loop
            }
        }
    }
    return arr;
}

console.log(getMCE())​

【讨论】:

  • 是的,这是显而易见的解决方案,遍历所有元素及其属性,这对于大型 DOM 来说代价太大。
  • -1 for break dance 因为它将在匹配的元素的第一个属性上中断。一个元素可以有多个匹配的属性。但总的来说,上面的代码似乎是目前唯一的解决方案。
  • @AsGoodAsItGets 您需要break dance,因为您只需要具有以mce_ 为前缀的属性的元素。如果它在该元素中找到具有mce_ 的属性,则脚本将该元素添加到集合中并继续处理另一个元素。无需解析其余属性...除非您收集的是属性名称,而不是元素。
  • @Joseph 你说得对,约瑟夫,我很抱歉。我忘了你是在收集元素而不是属性。我会亲自改进脚本以包含每个元素的属性,因为我计划在之后删除它们,但那是另一回事了。
【解决方案2】:

试试这个:

功能

//custom selector expression
$.extend($.expr[':'],{
attr:function(o,i,m){
  var attrs=$.getAttrAll(o),re=m[3],found=false;
  $.each(attrs,function(k,v){
  if(new RegExp(re).test(v)) { return found=true;}
});
return found;
} 
});
// get all atrributes of an element
$.getAttrAll=function(el){
  var rect = [];
  for (var i=0, attrs=el.attributes, len=attrs.length; i<len; i++){
    rect.push(attrs.item(i).nodeName);
  }
  return rect;
};

` 用法

// calling custom selector expression :attr(regexp)
$(function(){
  $('body').find(':attr("^mce_")').css({background:'yellow'});
});

HTML

<body>
  <p mce_style="height:50px" id="x" data-hello="hello">selected</p>
  <div not_mce_bogus="abc">not_mce_bogus</div>
  <div mce_href="http://rahenrangan.com">selected</div>
  <p>othrs</p>
</body>

【讨论】:

  • 这基本上是稍微优雅一些​​,但我怀疑性能稍差,基于 jQuery 的 Joseph 发布的代码重写。它仍然必须通过 DOM 遍历每个元素和每个属性。更重要的是,您提到的示例用法仅考虑 body 标记的直接子级,正确的用法是使用 find() 而不是 children() (尽管在您的简单 HTML 中它会起作用)。我想我必须接受这样一个事实,即没有更好的方法可以做到这一点。
【解决方案3】:

如果您不介意临时更改 DOM,一个选项是将 HTML 提取到字符串中并通过 RegExp 搜索属性。找到属性后,可以在 DOM 中附加一个“针”,以便使用 jQuery 选择元素。

这是一个工作概念(在控制台打开的情况下运行):

http://jsfiddle.net/skylar/N43Bm/

代码:

$.fn.extend({

    findAttributes: function(attribute) {

        var attributeFinder = new RegExp(attribute + '(.+)="', "gi");
        var elementHTML = this.html().replace(attributeFinder, "data-needle='pin' "+attribute+"$1=\"");

        this.html(elementHTML);

        return this.find("[data-needle=pin]").removeAttr('data-needle');
    }

});

console.log($("body").findAttributes('mce_'));

注意:我的正则表达式不是很好。在这个例子中,你必须比我更加小心。

【讨论】:

    【解决方案4】:

    试试这个:(我尝试用 * 代替 a 标签,但它为所有元素着色,包括那些没有 mce_style 属性的元素)

    a[mce_style] { color : red; }​
    

    演示:http://jsfiddle.net/Tcdmb/

    更多信息:https://developer.mozilla.org/en/CSS/Attribute_selectors

    【讨论】:

    • 好的。这在一定程度上解决了他的问题,但不能在 mce_*' to select all the elements having attributes with mce_` 中使用 * 或 % 作为前缀。
    猜你喜欢
    • 1970-01-01
    • 2013-03-31
    • 2013-09-28
    • 2021-11-03
    • 2020-10-05
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多