1

ユーザーがdivをクリックして選択および選択解除できる関数を作成しました。さて、私がやろうとしていたのは、一度aを押すとすべての選択を解除する関数でしたが、それは私のdivの一部しか選択解除しませんでした。コードは次のとおりです。

var divs = document.getElementsByClassName('fuori');
for(i = 0, j = divs.length; i < j; i++){
 divs[i].addEventListener('click', function(){
    if(!hasClass(this, 'selected')){
    this.className = this.className + " selected";
} else {
    removeClass(this, 'selected');
}
});
}

removeClass関数はこれです

function removeClass(ele,cls) {
    if (hasClass(ele,cls)) {
        var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)');
        ele.className=ele.className.replace(reg,' ');
    }
}

これはdeselectAllです

function deselectAll(){
    var selected = document.getElementsByClassName('selected');
    alert(selected.length);
    for (i = 0; i < selected.length; i++){
        removeClass(selected[i], 'selected');
    }
}

クリックによる選択と選択解除はシームレスに機能しますが、いくつかのdivを選択してaを押すと、すべてのdivの選択が解除されるのではなく、一部のdivのみが選択解除されます。

どうすればこれを修正できますか?そして、なぜそれが機能しないのですか?

ありがとうございました!

4

1 に答える 1

1

forそのループを変更してみてください:

for (var i = selected.length; --i >= 0; removeClass(selected[i], 'selected'));

からの戻り値getElementsByClassName()は、配列ではなく NodeList であり、「ライブ」です。つまり、クラスを削除して DOM を変更すると、リストも変更されます。

後退することで、問題を回避できます。これを行うこともできます:

while (selected.length) removeClass(selected[0], 'selected');

ところで、クラスを削除するために使用している正規表現はより簡単になる可能性があります。

function removeClass(ele,cls) {
    var reg = new RegExp('\\b' + cls + '\\b', 'g');
    ele.className=ele.className.replace(reg,' ');
}

JavaScript の正規表現で\bは、「単語の境界」を意味します。hasClass()また、クラス文字列が存在しない場合、置換は何もしないため、呼び出しても意味がありません。

編集— これは、一般的な規則であるハイフンが埋め込まれたクラス名では機能しないことがコメントで指摘されています。それに対処する必要がある場合は、次のようにするとうまくいくと思います。

function removeClass(ele,cls) {
    var reg = new RegExp('\\b' + cls.replace(/-/g, '\\b-\\b') + '\\b', 'g');
    ele.className=ele.className.replace(reg,' ');
}

またはそのテーマのバリエーション。

于 2012-09-13T17:24:10.410 に答える