为什么jQuery不会删除所有数据属性?

时间:2013-09-20 18:43:54

标签: javascript jquery

正如标题所说:为什么jQuery不会删除所有数据属性?

<div data-subject-name="Spanisch" data-subject-id="9" data-subject-alias="Spa" data-category-id="1"></div>
$.fn.removeAttrs = function(regex) {
    var regex = new RegExp(regex, "g");
    return this.each(function() {
        var _this = $(this);

        console.log(this.attributes);
        $.each(this.attributes, function(i, attrib){
            console.log(attrib);
            if (attrib && attrib.specified && regex.test(attrib.name)) {
                console.log(attrib.name);
                _this.removeAttr(attrib.name);
            }
        });
    });
};

$('div').removeAttrs('^(data-)');

这是http://jsfiddle.net/g2pXt/8/

我正在使用来自Remove multiple html5 data-attributes with jquery @Mathias Bynens的剪辑,但它无效。那么这个解决方案的问题是什么?

2 个答案:

答案 0 :(得分:6)

您的代码实际上有两个问题,每个问题都会部分掩盖另一个问题。

"test called multiple times on the same global regular expression instance will advance past the previous match."因此,每次使用相同的正则表达式执行.test时,都不是从字符串的开头搜索。我将regex.test(str)替换为str.search(regex)>=0来解决此问题。

此外,您的脚本似乎有索引问题,因为您正在循环中删除属性。我相信这是因为"Arrays and array-like objects with a length property...are iterated by numeric index, from 0 to length-1."在循环解决问题后立即删除所有属性(.removeAttr()将接受要删除的空格分隔的属性列表。)

$.fn.removeAttrs = function(regex) {
    var regex = new RegExp(regex, "g");
    return this.each(function() {
        var _this = $(this);
        var removethese = '';
        $.each(this.attributes, function(i, attrib){
            if (attrib && attrib.specified && attrib.name.search(regex)>=0) {
                removethese += ' '+attrib.name;
            }
        });
        _this.removeAttr(removethese);
    });
};

http://jsfiddle.net/mblase75/YHyjC/


请注意,以这种方式使用.removeAttr()实际上是第二次重复循环,因此为了最大限度地提高效率,您应该重新调整代码并使用向后计算for循环通过this.attributes并同时删除它们。但是,对于一组短的属性,性能增益将是最小的。

$.fn.removeAttrs = function(regex) {
    var regex = new RegExp(regex, "g");
    return this.each(function() {
        var _this = $(this);
        for (var i=this.attributes.length-1; i>=0; i--){
            var attrib = this.attributes[i];
            if (attrib && attrib.specified && attrib.name.search(regex)>=0) {
                _this.removeAttr(attrib.name);
            }
        }; // end for
    });
};

http://jsfiddle.net/mblase75/Zm4qR/

答案 1 :(得分:2)

你的内部循环正在迭代在其下面发生变化的项目列表。

最安全的路由是从属性列表的末尾向后使用直接JS循环,因此在删除前一个元素时不会跳过元素:

for ( var i = this.attributes.length - 1; i >= 0; --i ) {
  var attrib = this.attributes[i];

  if (attrib && attrib.specified && regex.test(attrib.name)) 
  {
    console.log(attrib.name);
    _this.removeAttr(attrib.name);
  }
}

更新了jsFiddle,包括简化的正则表达式:http://jsfiddle.net/g2pXt/36/