简体   繁体   中英

Can a javascript function apply to all elements of a certain CSS class?

I have a nav bar where each button changes the background of the body. They each change it to a different color. I have created onmouseover and onmouseout functions for each button to achieve this. However, I wonder if there is a way to just write one of each function by just referring to them by their class? They all have the same class of button . Is there a way a function can apply to all elements of a certain class? My code:

function whichButton(x) {
    if (x==1)
        return "red";
    if (x==2)
        return "green";
    if (x==3)
        return "blue";
    if (x==4)
        return "orange";
    if (x==0)
        return initBG;
}

button1.onmouseover = function() {
    document.body.style.backgroundColor = whichButton(1);
}

button1.onmouseout = function() {
    document.body.style.backgroundColor = whichButton(0);
}

button2.onmouseover = function() {
    document.body.style.backgroundColor = whichButton(2);
}

button2.onmouseout = function() {
    document.body.style.backgroundColor = whichButton(0);
}

button3.onmouseover = function() {
    document.body.style.backgroundColor = whichButton(3);
}

button3.onmouseout = function() {
    document.body.style.backgroundColor = whichButton(0);
}

button4.onmouseover = function() {
    document.body.style.backgroundColor = whichButton(4);
}

button4.onmouseout = function() {
    document.body.style.backgroundColor = whichButton(0);
}

initBG just saves the initial background of the page.

I have tried this:

document.getElementsByClassName('button').onmouseover = function() {
    document.body.style.backgroundColor = whichButton(1);
}

but it doesn't trigger the function. And I guess to do this, I'd also need to have a way to read the elements' ID as a string so I could get it's number...

This is more out of curiosity than necessity, just trying to find ways to keep my code small! I could see this being useful in many applications so I'd love to learn more about this!

Corresponding HTML:

<div id="navbar">

<p id="button1" class="button">Red</p><p id="button2" class="button">Blue</p><p id="button3" class="button">Green</p><p id="button4" class="button">Orange</p>

</div>

Here is my suggestion to solve it: Use the data attribute and iterate over all elements with the given class.

 function applyColor(element) { var color = element.getAttribute('data-bg'); document.body.style.backgroundColor = color; } var buttons = document.getElementsByClassName("button"); for (var i = 0; i < buttons.length; i++) { buttons[i].addEventListener("mouseover", function() { applyColor(this); }, false); } 
 <nav> <button class="button" data-bg="red">red</button> <button class="button" data-bg="blue">blue</button> <button class="button" data-bg="yellow">yellow</button> <button class="button" data-bg="green">green</button> <button class="button" data-bg="pink">pink</button> <button class="button" data-bg="magenta">magenta</button> </nav> 

getElementsByClassName returns a collection. So you will have to loop over it and you shall be good.

var buttons = document.getElementsByClassName('button');

[].forEach.call(buttons, function (button){
    var id = parseInt(button.id.split("").reverse().join("")); //This will give you the number from the id
    button.onmouseover = = function() {
        document.body.style.backgroundColor = whichButton(id);
    }

    button.onmouseout = function() {
        document.body.style.backgroundColor = whichButton(0);
    }

});

To ensure ES6 compatibility, there is much better way.

var buttons = document.getElementsByClassName("button");
for (button of buttons) {
    var id = parseInt(button.id.split("").reverse().join("")); //This will give you the number from the id
    button.onmouseover = = function() {
        document.body.style.backgroundColor = whichButton(id);
    }

    button.onmouseout = function() {
        document.body.style.backgroundColor = whichButton(0);
    }
}

As previously stated, getElementsByClassName returns a collection and you can't just add the event to the collection in a way that you can in jQuery. To do this is pure JS, you need to use a for loop and then attach the event to each individual element as below:

var buttons = document.getElementsByClassName('button');
for (var i = 0; i < buttons.length; i++) {
    buttons[i].onmouseover = function (event) {
        var colour = event.target.className.split(" ")[1];       
        document.body.style.backgroundColor = colour;
    }
}

http://jsfiddle.net/andyfurniss/1n5vann9/

The first comment actually solved it for me. I did this:

document.onmouseover = function() {
    var x = event.target;
    y = x.id.toString().replace('button','');
    if (y > 0 && y <= 4)
        document.body.style.backgroundColor = whichButton(y);
}

document.onmouseout = function() {
    var x = event.target;
    y = x.id.toString().replace('button','');
    if (y > 0 && y <= 4)
        document.body.style.backgroundColor = whichButton(0);
}

If I mouse over a "button", it removes the word "button", leaving the number (1-4), then sends that to my whichButton function to decice which colour to use. Nice and simple, works for me.

You can use event delegation, which means attaching an event listener to an ancestor, then inspecting the event.target to decide what to do.

Demo: http://jsfiddle.net/a58tj1ak/

// given your HTML and whichButton function like this:
function whichButton(x) {
    var initBG = '#fff';
    if (x==1)
        return "red";
    if (x==2)
        return "green";
    if (x==3)
        return "blue";
    if (x==4)
        return "orange";
    if (x==0)
        return initBG;
}

// get the buttons into an array
var buttons = [].slice.call(document.getElementsByClassName('button'));
// add event listener to the #navbar element
document.getElementById('navbar').addEventListener('mouseover', function(e){
   // target is an element being hovered
   var target = e.target;
    // check if the target is in the array of buttons
    var index = buttons.indexOf( e.target );
    if( index > -1 ){
        document.body.style.backgroundColor = whichButton(index + 1)
    }
    else {
        document.body.style.backgroundColor = whichButton(0);   
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM