web-dev-qa-db-de.com

klasse mit JavaScript hinzufügen

Ich schreibe etwas Vanilla-JavaScript, um ein Nizza-Navigationsmenü zu erstellen. Ich bin fest entschlossen, eine aktive Klasse hinzuzufügen.

Ich bekomme Elemente nach Klassennamen NICHT durch ID. Der folgende Code funktioniert, wenn er durch eine ID ersetzt wird. Ich muss ihn jedoch auf mehrere Elemente anwenden. 

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");
}

Bitte keine Antworten mit jQuery.

35
vincentieo

document.getElementsByClassName gibt eine Knotenliste zurück. Sie müssen also die Liste durchlaufen und das Ereignis an einzelne Elemente binden. So was...

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");
    }
}
42
mohkhan

In Ihrem Snippet ist button eine Instanz von NodeList, an die Sie weder einen Ereignis-Listener direkt anhängen noch die Eigenschaften der Elemente className direkt ändern können.
Am besten delegieren Sie die Veranstaltung:

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);

Ich vermute natürlich, dass die Klasse active entfernt werden muss, sobald das Ereignis mouseout ausgelöst wird. Sie könnten in Betracht ziehen, einen zweiten Delegator dafür zu verwenden, aber Sie könnten Hängen Sie auch einen Event-Handler an das eine Element mit der Klasse active an:

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);

Mit diesem Code gibt es einige Verbesserungsmöglichkeiten, aber ich werde hier nicht den ganzen Spaß haben ;-).

Überprüfen Sie die Geige hier

7

Hier ist eine von Jquery 2.1.1 angepasste Methode, bei der ein dom-Element anstelle eines Jquery-Objekts verwendet wird (Jquery wird also nicht benötigt). Enthält Typenprüfungen und Regex-Ausdrücke:

function addClass(element, value) {
    // Regex terms
    var rclass = /[\t\r\n\f]/g,
        rnotwhite = (/\S+/g);

    var classes,
        cur,
        curClass,
        finalValue,
        proceed = typeof value === "string" && value;

    if (!proceed) return element;

    classes = (value || "").match(rnotwhite) || [];

    cur = element.nodeType === 1
        && (element.className
                ? (" " + element.className + " ").replace(rclass, " ")
                : " "
        );

    if (!cur) return element;

    var j = 0;

    while ((curClass = classes[j++])) {

        if (cur.indexOf(" " + curClass + " ") < 0) {

            cur += curClass + " ";

        }

    }

    // only assign if different to avoid unneeded rendering.
    finalValue = cur.trim();

    if (element.className !== finalValue) {

        element.className = finalValue;

    }

    return element;
};
2

getElementsByClassName() gibt HTMLCollection zurück, damit Sie dies versuchen können

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

Bearbeiten

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");
   }
}
0
Arda

Ich benutze gerne eine benutzerdefinierte "foreach" -Funktion für diese Art von Dingen:

function Each( objs, func )
{
    if ( objs.length ) for ( var i = 0, ol = objs.length, v = objs[ 0 ]; i < ol && func( v, i ) !== false; v = objs[ ++i ] );
    else for ( var p in objs ) if ( func( objs[ p ], p ) === false ) break;
}

(Kann mich nicht erinnern, wo ich die obige Funktion gefunden habe, aber es war sehr nützlich.)

Dann, nachdem Sie Ihre Objekte (in diesem Beispiel auf elements) abgerufen haben, tun Sie es einfach

Each( elements, function( element )
{
    element.addEventListener( "mouseover", function()
    {
        element.classList.add( "active" );
        //element.setAttribute( "class", "active" );
        element.setAttribute( "src", "newsource" );
    });

    // Remove class and new src after "mouseover" ends, if you wish.
    element.addEventListener( "mouseout", function()
    {
        element.classList.remove( "active" );
        element.setAttribute( "src", "originalsource" );
    });
});

classList ist eine einfache Methode für die Handhabung von Elementklassen. Benötigt nur ein Shim für ein paar Browser. Wenn Sie setAttribute verwenden müssen, müssen Sie daran denken, dass will die vorherigen Werte überschreibt.

BEARBEITEN: Vergessen Sie nicht zu erwähnen, dass Sie bei einigen IE Versionen attachEvent anstelle von addEventListener verwenden müssen. Testen Sie mit if ( document.addEventListener ) {...}.

0
ojrask

In ECMAScript 5th Edition gibt es eine forEach-Schleife für ein Array.

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

Array.prototype.forEach.call(buttons,function(button) { 
    button.setAttribute("class", "active");
    button.setAttribute("src", "images/arrows/top_o.png"); 
});
0
ketan

Fügen Sie einfach einen Klassennamen am Anfang der Funktion hinzu. Die 2. und 3. Argumente sind optional und der Zauber wird für Sie erledigt!

function getElementsByClass(searchClass, node, tag) {

  var classElements = new Array();

  if (node == null)

    node = document;

  if (tag == null)

    tag = '*';

  var els = node.getElementsByTagName(tag);

  var elsLen = els.length;

  var pattern = new RegExp('(^|\\\\s)' + searchClass + '(\\\\s|$)');

  for (i = 0, j = 0; i < elsLen; i++) {

    if (pattern.test(els[i].className)) {

      classElements[j] = els[i];

      j++;

    }

  }

  return classElements;

}
0
Yoni