codeguerrilla
codeguerrilla

Reputation: 462

getElementsByClassName not working in Firefox

I wrote this script for a 5 star ratings system I made and it makes the stars light up as the user hovers over them, for example: if a user is hovered over the third star, that one shows the lit star image as well as the first two. The script works in all newer browsers except FireFox. I have racked my brain over this for a while and cannot figure out why its not working in firefox. Any help is appreciated. Also, I am only interested in responses about raw Javascript, not JQuery or any other framework. Thanks a bunch.

function btnSwap(){
var myBtns = document.getElementsByClassName('btns');
for(i=0; i<myBtns.length; i++){
    var elem = document.getElementById(myBtns[i].id);
    elem.src = "images/"+"starNorm.png";
    elem.onmouseover = btnOver;
    elem.onmouseout = btnOut;
    function btnOver(){
        var lit = document.getElementById(this.id);
        if(lit.id == "rb1"){
        lit.src = "images/"+"starOver.png";
        }
        if(lit.id == "rb2"){
        lit.src = "images/"+"starOver.png";
        document.getElementById('rb1').src = "images/"+"starOver.png";
        }
        if(lit.id == "rb3"){
        lit.src = "images/"+"starOver.png";
        document.getElementById('rb1').src = "images/"+"starOver.png";
        document.getElementById('rb2').src = "images/"+"starOver.png";
        }
        if(lit.id == "rb4"){
        lit.src = "images/"+"starOver.png";
        document.getElementById('rb1').src = "images/"+"starOver.png";
        document.getElementById('rb2').src = "images/"+"starOver.png";
        document.getElementById('rb3').src = "images/"+"starOver.png";
        }
        if(lit.id == "rb5"){
        lit.src = "images/"+"starOver.png";
        document.getElementById('rb1').src = "images/"+"starOver.png";
        document.getElementById('rb2').src = "images/"+"starOver.png";
        document.getElementById('rb3').src = "images/"+"starOver.png";
        document.getElementById('rb4').src = "images/"+"starOver.png";
        }

}

function btnOut(){
        var lit = document.getElementById(this.id);
        if(lit.id == "rb1"){
        lit.src = "images/"+"starNorm.png";
        }
        if(lit.id == "rb2"){
        lit.src = "images/"+"starNorm.png";
        document.getElementById('rb1').src = "images/"+"starNorm.png";
        }
        if(lit.id == "rb3"){
        lit.src = "images/"+"starNorm.png";
        document.getElementById('rb1').src = "images/"+"starNorm.png";
        document.getElementById('rb2').src = "images/"+"starNorm.png";
        }
        if(lit.id == "rb4"){
        lit.src = "images/"+"starNorm.png";
        document.getElementById('rb1').src = "images/"+"starNorm.png";
        document.getElementById('rb2').src = "images/"+"starNorm.png";
        document.getElementById('rb3').src = "images/"+"starNorm.png";
        }
        if(lit.id == "rb5"){
        lit.src = "images/"+"starNorm.png";
        document.getElementById('rb1').src = "images/"+"starNorm.png";
        document.getElementById('rb2').src = "images/"+"starNorm.png";
        document.getElementById('rb3').src = "images/"+"starNorm.png";
        document.getElementById('rb4').src = "images/"+"starNorm.png";
        }


    }
}

}

Upvotes: 2

Views: 1069

Answers (1)

Nathan Wall
Nathan Wall

Reputation: 10614

Don't put the function declarations inside the for loop.

function btnSwap(){

    var myBtns = document.getElementsByClassName('btns');

    // begin loop
    for(i=0; i<myBtns.length; i++){
        var elem = document.getElementById(myBtns[i].id);
        elem.src = "images/"+"starNorm.png";
        elem.onmouseover = btnOver;
        elem.onmouseout = btnOut;
    }

    // outside the loop.. now function declarations.

    function btnOver(){
        var lit = document.getElementById(this.id);
        if(lit.id == "rb1"){
        lit.src = "images/"+"starOver.png";
        }
        if(lit.id == "rb2"){
        lit.src = "images/"+"starOver.png";
        document.getElementById('rb1').src = "images/"+"starOver.png";
        }
        if(lit.id == "rb3"){
        lit.src = "images/"+"starOver.png";
        document.getElementById('rb1').src = "images/"+"starOver.png";
        document.getElementById('rb2').src = "images/"+"starOver.png";
        }
        if(lit.id == "rb4"){
        lit.src = "images/"+"starOver.png";
        document.getElementById('rb1').src = "images/"+"starOver.png";
        document.getElementById('rb2').src = "images/"+"starOver.png";
        document.getElementById('rb3').src = "images/"+"starOver.png";
        }
        if(lit.id == "rb5"){
        lit.src = "images/"+"starOver.png";
        document.getElementById('rb1').src = "images/"+"starOver.png";
        document.getElementById('rb2').src = "images/"+"starOver.png";
        document.getElementById('rb3').src = "images/"+"starOver.png";
        document.getElementById('rb4').src = "images/"+"starOver.png";
        }

    }

    function btnOut(){
        var lit = document.getElementById(this.id);
        if(lit.id == "rb1"){
        lit.src = "images/"+"starNorm.png";
        }
        if(lit.id == "rb2"){
        lit.src = "images/"+"starNorm.png";
        document.getElementById('rb1').src = "images/"+"starNorm.png";
        }
        if(lit.id == "rb3"){
        lit.src = "images/"+"starNorm.png";
        document.getElementById('rb1').src = "images/"+"starNorm.png";
        document.getElementById('rb2').src = "images/"+"starNorm.png";
        }
        if(lit.id == "rb4"){
        lit.src = "images/"+"starNorm.png";
        document.getElementById('rb1').src = "images/"+"starNorm.png";
        document.getElementById('rb2').src = "images/"+"starNorm.png";
        document.getElementById('rb3').src = "images/"+"starNorm.png";
        }
        if(lit.id == "rb5"){
        lit.src = "images/"+"starNorm.png";
        document.getElementById('rb1').src = "images/"+"starNorm.png";
        document.getElementById('rb2').src = "images/"+"starNorm.png";
        document.getElementById('rb3').src = "images/"+"starNorm.png";
        document.getElementById('rb4').src = "images/"+"starNorm.png";
        }

    }
}

Explanation

Firefox respects conditional code blocks which wrap function declarations. For example:

if (true) {
    function a() { return 1; }
} else {
    function a() { return 2; }
}
a(); // => Chrome: 2, Firefox: 1

Since a for code block might not be executed, Firefox tries to respect the conditional nature of the for loop. You can see this more directly in a while (false) loop.

while(false) {
    function a() { return 'a'; }
}
a(); // => Chrome: 'a', Firefox: Throws an error.

In Firefox, a is never defined because the condition never succeeds.

However, if there is a code block which will always be executed no matter the condition, the function definition will be hoisted. We can see this in a do...while loop.

var x = a;
do {
    function a() { return 'a'; }
} while(false);
x(); // => Both browsers: 'a'

No problem hoisting here because a do...while code block is always guaranteed to execute.


Also, is there a reason you're doing stuff like this?

var elem = document.getElementById(myBtns[i].id)

There's no need to get an element by id if you already have it. Just use

var elem = myBtns[i];

Upvotes: 1

Related Questions