2013-09-20 4 views
3

как заголовок говорит: Почему 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, но он не работает. так в чем проблема этого решения?

+0

Если вы смотрите консоль, вы увидите сообщение об ошибке (в хроме). сначала исправить ошибки. Затем, если вы посмотрите вывод своих консолей, вы увидите, что некоторые из них удаляются, а некоторые из них этого не делают. –

+0

Работает, если вы измените его на jQuery-1.9.1. Не уверен, почему он не работает с 1.10.1. Дает мне отрицательную ошибку доступа в 'SetDocument()' (я использую IE 9) – Pete

+0

i обновил jdfiddle ... так что не ошибка для меня в firefox и chrome. @Pete: не работает для меня с 1.9.1 – JuKe

ответ

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 a d удаляет их одновременно. Однако для одного короткого набора атрибутов прирост производительности будет минимальным.

$.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/

+0

Спасибо ... это решение проблемы! – JuKe

+0

Добавлен второй вариант, который более оптимизирован, но немного отличается от исходного кода. – Blazemonger

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/

+0

Стоит объяснить, почему упрощенное регулярное выражение помогает решить проблему. – Blazemonger

Смежные вопросы