Creating a loop from a series of onMouseOver Events

倾然丶 夕夏残阳落幕 提交于 2019-12-13 06:43:03

问题


how can I create a loop out of this function.

window.onload = function makeHalo() {
    document.getElementById("d1").onmouseover = function() {
        this.id ="d1On";
        this.className="hover";
        document.getElementById("menu1").style.color="#6DC5E6";
    };
    document.getElementById("menu1").onmouseover = function() {
        this.style.color="#6DC5E6";
        document.getElementById("d1").className="hover";
        document.getElementById("d1").id="d1On";
    };

    document.getElementById("d1").onmouseout = function() {
        this.id ="d1";
        this.className="";
        document.getElementById("menu1").style.color="#FFFFFF";
    };
    document.getElementById("menu1").onmouseout = function() {
        this.style.color="#FFFFFF";
        document.getElementById("d1On").className="";
        document.getElementById("d1On").id="d1";
    };

    document.getElementById("d2").onmouseover = function() {
        this.id ="d2On";
        this.className="hover";
        document.getElementById("menu2").style.color="#6DC5E6";
    };
    document.getElementById("menu2").onmouseover = function() {
        this.style.color="#6DC5E6";
        document.getElementById("d2").className="hover";
        document.getElementById("d2").id="d2On";
    };

    document.getElementById("d2").onmouseout = function() {
        this.id ="d2";
        this.className="";
        document.getElementById("menu2").style.color="#FFFFFF";
    };
    document.getElementById("menu2").onmouseout = function() {
        this.style.color="#FFFFFF";
        document.getElementById("d2On").className="";
        document.getElementById("d2On").id="d2";
    };
}

The function pretty much learns the ID of an image when its hovered, changes the ID of that element, adds a class to the element, and changes the color of another element

The second part learns the ID of a list item when its hovered, changes its color, and changes the ID of the other image element and adds a class to that element as well.

The onmouseout simply resets everything.

On the actual HTML page, it is a menu page with lists. Below there a continent map, which is a background image. When you hover over a list item, it swaps out a point on a map with another picture for an indicator. You can also hover the points on the map to change the color of the links on the lists.

I tried doing something like this, but the loop only goes to the last iteration for some of the elements. The links change color fine, but it will only swap the picture for "d43" regardless of what link I hover over.

window.onload = function makeHalo() {
    var i = 1;
    for (i=1; i<44; i++) {
        var menu = "menu"+i;
        var d = "d"+i;
        var On = "d"+i+"On";
        document.getElementById(d).onmouseover = function() {
            this.id = On;
            this.className="hover";
            document.getElementById(menu).style.color="#6DC5E6";
        };
        document.getElementById(menu).onmouseover = function() {
            this.style.color="#6DC5E6";
            document.getElementById(d).className="hover";
            document.getElementById(d).id=On;
        };

        document.getElementById(d).onmouseout = function() {
            this.id = d;
            this.className="";
            document.getElementById(menu).style.color="#FFFFFF";
        };
        document.getElementById(menu).onmouseout = function() {
            this.style.color="#FFFFFF";
            document.getElementById(On).className="";
            document.getElementById(On).id=d;
        };
    }
}

Any help will be greatly appreciated.

Thanks.


回答1:


The primary technical issue you're facing is that you're creating closures in a loop. Each one of those callbacks closes over the same i variable, whose value will be the same for each of the callbacks (its value after the final iteration). This is fixed by wrapping the body of the loop in its own function that receives i as an argument, thus creating a local copy on each iteration.

There are a number of style and performance issues, as well:

  • The bodies of those callbacks are in many cases exactly the same (the mouseover and mouseout pairs end up dong the same work in each block).
  • You're retrieving the same elements by ID repeatedly. This is unnecessary; you should save a reference.
  • You're identifying the state of an element by changing its ID. This isn't generally how you want to handle this. An ID shouldn't change.

I would write it more like this (addressing the closure issue and the first two bullet items above (not addressing the ID problem)):

for (var i = 1; i <= 2; i++) {
    (function(i) {
        var d = document.getElementById("d" + i);
        var menu = document.getElementById("menu" + i);
        d.onmouseover = menu.onmouseover = function() { 
            d.id = "d" + i + "On"; 
            d.className = "hover";
            menu.style.color = "#6DC5E6";
        };
        d.onmouseout = menu.onmouseout = function() { 
            d.id = "d" + i; 
            d.className = "";
            menu.style.color = "#FFFFFF";
        };
    })(i);
}

This handles just two elements; simply change the loop max to make it work for more.

You can see a working demo here:

  • http://jsfiddle.net/ezYtq/



回答2:


Is your last div in your HTML "d43" or is it "d44"? Your loop will run through d1 through d43 because you have i<44 which means when i is 44 it will exit the loop so it will stop at d43.

If you want it to get to d44, then either change the condition to: i <= 44 or change it to i < 45

By the way is there is reason you are not using jQuery it's design to make things like this much easier, in several ways. Maybe you listed what you were actually trying to accomplish with this code for example whether it's a menu system or something we might be able to suggest better approaches.




回答3:


No need for JavaScript here... just use the CSS :hover pseudo-class.

But, to answer your question:

  • Do not change the id of your element. This seems fundamentally wrong. Change, add, or remove a class instead. What are you trying to accomplish by changing the id?
  • Don't keep track of id's, just keep track of element references directly.
  • Most importantly, when you are doing your loop, by the time the functions are called, the value of i is 45, for all elements. Solve this by passing i to a function that creates your event handlers:
window.onload = function makeHalo() {  
    for (var i = 1; i < 44; i++) {
        (function (i) {
            var menu = document.getElementById("menu" + i);
            var d = document.getElementById("d" + i);
            function over () {
                d.className = "hover";  
                menu.style.color = "#6DC5E6";  
            }
            d.onmouseover = over;
            menu.onmouseover = over;

            function out () {  
                d.className = "";  
                menu.style.color = "#FFFFFF";  
            }
            d.onmouseout = out;
            menu.onmouseout = out;
        })(i);
    }  
}


来源:https://stackoverflow.com/questions/8672416/creating-a-loop-from-a-series-of-onmouseover-events

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!