3

正如标题所说:为什么 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/

我正在使用带有 jquery @Mathias Bynens 的 Remove multiple html5 data-attributes 中的片段,但它不起作用。那么这个解决方案的问题是什么?

4

2 回答 2

6

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

"test在同一个全局正则表达式实例上多次调用将超过上一次匹配。" 结果,每隔一次您.test使用相同的正则表达式执行时,它都不是从字符串的开头进行搜索。我换成regex.test(str)str.search(regex)>=0解决这个问题。

此外,您的脚本似乎存在索引问题,因为您在循环中间删除了属性。我相信这是因为“具有长度属性的数组和类似数组的对象......由数字索引迭代,从 0 到 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/

于 2013-09-20T19:10:01.913 回答
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/

于 2013-09-20T19:09:23.613 回答