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で複数の html5 データ属性を削除するから切り取ったものを使用していますが、機能していません。このソリューションの問題は何ですか?

4

2 に答える 2

6

コードには実際に 2 つの問題があり、それぞれが部分的に他方を隠しています。

test同じグローバル正規表現インスタンスで複数回呼び出されると、前の一致を超えて進みます。」その結果、同じ正規表現を使用して実行するたび.testに、文字列の先頭から検索されませんでした。この問題を解決するために置き換えregex.test(str)ました。str.search(regex)>=0

さらに、ループの途中で属性を削除していたため、スクリプトにインデックス作成の問題があるようです。これは、「長さプロパティを持つ配列および配列のようなオブジェクトは、0 から長さ 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()すると、事実上ループが 2 回繰り返されることに注意してください。そのため、最大の効率を得るには、コードを再構築し、逆方向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 に答える