36

素敵なナビゲーション メニューを作成するために、いくつかのバニラ JavaScript を作成しています。アクティブなクラスの追加に行き詰まっています。

IDではなくクラス名で要素を取得しています。以下のコードは id で置き換えた場合に機能しますが、複数の要素に適用する必要があります。

HTML

<img class="navButton" id="topArrow" src="images/arrows/top.png" />
<img class="navButton" id="rightArrow" src="images/arrows/right.png" />

JS

var button = document.getElementsByClassName("navButton");

button.onmouseover = function() {
    button.setAttribute("class", "active");
    button.setAttribute("src", "images/arrows/top_o.png");
}

jQuery を含む回答はありません。

4

7 に答える 7

45

document.getElementsByClassNameノードリストを返します。そのため、リストを繰り返し処理し、イベントを個々の要素にバインドする必要があります。このような...

var buttons = document.getElementsByClassName("navButton");

for(var i = 0; i < buttons.length; ++i){
    buttons[i].onmouseover = function() {
        this.setAttribute("class", "active");
        this.setAttribute("src", "images/arrows/top_o.png");
    }
}
于 2013-07-30T10:45:59.787 に答える
7

スニペットでは、buttonは のインスタンスであり、イベント リスナーを直接アタッチすることも、要素のプロパティを直接NodeList変更することもできません。 あなたの最善の策は、イベントを委任することです:className

document.body.addEventListener('mouseover',function(e)
{
    e = e || window.event;
    var target = e.target || e.srcElement;
    if (target.tagName.toLowerCase() === 'img' && target.className.match(/\bnavButton\b/))
    {
        target.className += ' active';//set class
    }
},false);

もちろん、イベントが発生したらactiveクラスを削除する必要があると思いmouseoutます。そのために 2 番目のデリゲーターを使用することを検討することもできactiveますが、クラスを持つ 1 つの要素にイベント ハンドラーをアタッチすることもできます。

document.body.addEventListener('mouseover',function(e)
{
    e = e || window.event;
    var oldSrc, target = e.target || e.srcElement;
    if (target.tagName.toLowerCase() === 'img' && target.className.match(/\bnavButton\b/))
    {
        target.className += ' active';//set class
        oldSrc = target.getAttribute('src');
        target.setAttribute('src', 'images/arrows/top_o.png');
        target.onmouseout = function()
        {
            target.onmouseout = null;//remove this event handler, we don't need it anymore
            target.className = target.className.replace(/\bactive\b/,'').trim();
            target.setAttribute('src', oldSrc);
        };
    }
},false);

このコードには改善の余地がありますが、ここですべてを楽しむことはできません ;-)。

ここでフィドルを確認してください

于 2013-07-30T10:55:43.843 に答える
0

getElementsByClassName()HTMLCollection を返すので、これを試すことができます

var button = document.getElementsByClassName("navButton")[0];

編集

var buttons = document.getElementsByClassName("navButton");
for(i=0;buttons.length;i++){
   buttons[i].onmouseover = function(){
     this.className += ' active' //add class
     this.setAttribute("src", "images/arrows/top_o.png");
   }
}
于 2013-07-30T10:47:01.680 に答える
0

ECMAScript 5th Edition には、配列の forEach ループが組み込まれています。

var buttons = document.getElementsByClassName("navButton");

Array.prototype.forEach.call(buttons,function(button) { 
    button.setAttribute("class", "active");
    button.setAttribute("src", "images/arrows/top_o.png"); 
});
于 2013-07-30T11:01:25.680 に答える