Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript addEventListener is not working

I'm writing a simple chrome extension that lists all the open tabs, I have this code on it

function changeTab(tabID){
  chrome.tabs.update(tabID,{active:false})
}

chrome.windows.getCurrent({populate: true},function (window){
  list = document.getElementById('open-tabs');
  for (var i = 0; i < window.tabs.length; i++)
  {
    var li = document.createElement('li');
    var element = document.createElement('a');
    element.setAttribute('href','#');
    element.innerHTML = window.tabs[i].title;
    element.addEventListener("click",function(){
      changeTab(window.tabs[i].id);
    },false);
    li.appendChild(element);
    list.appendChild(li);
  }
});

It lists the open tabs, but doesn't seem to add the onClick event, when I checked the chrome console I get this

chrome console

Why is not adding the event correctly?

--edit-- Adding the html if it helps

<!doctype html>
<html>
<head>
    <title>Count Me</title>
    <link rel="stylesheet" href="popup.css" type="text/css">
    <script src="popup.js"></script>
</head>
<body>
    <div id="main">
        <ul id="open-tabs"></ul>
    </div>
</body>
</html>

Edit2

I tried using the sugestion given on an answer using the .bind(this,i) but still doesn't work, I added console.log() to see what's happening, and it seems it's not going inside the addEventListener heres the code with the log calls:

function changeTab(tabID){
  chrome.tabs.update(tabID,{active:false})
}

chrome.windows.getCurrent({populate: true},function (window){
  list = document.getElementById('open-tabs');
  for (var i = 0; i < window.tabs.length; i++)
  {
    var li = document.createElement('li');
    var element = document.createElement('a');
    element.setAttribute('href','#');
    element.innerHTML = window.tabs[i].title;
    console.log('before');
    console.log(window.tabs[i].id);
    element.addEventListener("click",function(iVal){
      console.log('inside');
      changeTab(window.tabs[iVal].id);
    }.bind(this,i),false);
    console.log('after');
    console.log(window.tabs[i].id);
    li.appendChild(element);
    list.appendChild(li);
  }
});

As you can see I have a Before and After console.log() as well as inside the addEventListener and it doesn't seem to call anything inside the addEventListener as you can see here:

chrome console

It's calling the console.log inside the addEventListener but still isn't working

chrome console 3

like image 356
Osukaa Avatar asked Mar 24 '23 21:03

Osukaa


1 Answers

Try adding a closure around the function

(function(num) {
    element.addEventListener("click",function(){
       changeTab(window.tabs[num].id);
    },false);
})(i)

The event will be executed a later stage when you click the element. So when the for loop is completed, i always points to last iterated value.

So enclosing it in an anonymous function creates a closure around the variable which will be available at the time the click event occurs.

like image 67
Sushanth -- Avatar answered Apr 06 '23 00:04

Sushanth --