简体   繁体   中英

addEventListener Created an Infinite Loop

I added an event listener and it created an infinite loop I really don't get what I did wrong.

What happen is it keeps clicking the images by itself

Here's my code:

function attachOnClickEvent(cases,theme,debut,capture){
    var images=document.getElementsByTagName('img');
    for(var i=0;i<images.length;i++){
        images[i].addEventListener("click",x(cases,theme,debut,capture),false);
    }
};

var x=function(cases,theme,debut,capture){newImage(this,cases,theme,debut,capture);};

function newImage(elem,cases,theme,debut,capture){
    var images=preloadImages(cases,theme);
    var imgTab=document.getElementsByTagName('img');
    var Id=elem.id;
    elem.src=images[randomTab[Id]];

}; 

Hope someone can find my mistake.. Thanks!

  1. getElementsByTagName is returning a live NodeList
  2. You are invoking your function x each time instead of adding it as a handler
  3. A new <img> is created
  4. the NodeList has it's length increased by 1
  5. The next iteration is the same distance away from the end as the previous one

There are two things you need to consider, firstly as I mention in 2 , you're invoking x when you aren't meaning to. Secondly, you may avoid some problems with live lists by looping downwards


One fix to get your desired result may be to rewrite attachOnClickEvent like this

function attachOnClickEvent(cases, theme, debut, capture) {
    var images = document.getElementsByTagName('img'),
        handler = function (e) {
            return x(cases, theme, debut, capture);
        },
        i;
    for (i = images.length - 1; i >= 0; --i) {
        images[i].addEventListener("click", handler, false);
    }
}

One issue would seem to be that you are not using callbacks properly.

Callbacks need to be function objects and cannot be returned as you are intending.

function (cases, theme, debut, capture) {
    return function() { newImage(this, cases, theme, debut, capture); };
}

Try returning an anonymous function.

Would be better to see how you're calling these functions, but I noticed that on this line:

images[i].addEventListener("click",x(cases,theme,debut,capture),false);

You are calling your function x , rather than assigning it as the event listener. Since that function adds an image to the page, the loop never completes, since it iterates through all images on the page. This line should instead be:

images[i].addEventListener("click", x , false );

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