Adding 'Click' Event Listeners in Loop

addEventListener using for loop and passing values

Closures! :D

This fixed code works as you intended:

// Function to run on click:function makeItHappen(elem, elem2) {    var el = document.getElementById(elem);    el.style.backgroundColor = "red";    var el2 = document.getElementById(elem2);    el2.style.backgroundColor = "blue";}
// Autoloading function to add the listeners:var elem = document.getElementsByClassName("triggerClass");
for (var i = 0; i < elem.length; i += 2) { (function () { var k = i + 1; var boxa = elem[i].parentNode.id; var boxb = elem[k].parentNode.id; elem[i].addEventListener("click", function() { makeItHappen(boxa,boxb); }, false); elem[k].addEventListener("click", function() { makeItHappen(boxb,boxa); }, false); }()); // immediate invocation}
<div class="container">  <div class="one" id="box1">    <p class="triggerClass">some text</p>  </div>  <div class="two" id="box2">    <p class="triggerClass">some text</p>  </div></div>
<div class="container"> <div class="one" id="box3"> <p class="triggerClass">some text</p> </div> <div class="two" id="box4"> <p class="triggerClass">some text</p> </div></div>

Adding 'click' event listener using 'for' loop

This is because your event handler will be called later (by user action), and that time, i isn't what you want. You have to use closure to keep it internal.

var links = ['https://www.facebook.com/', 'https://twitter.com', 'https://soundcloud.com'];
function openURL(link) { console.log(link);};

window.onload = function () {
var listElement = document.getElementsByTagName('li');
for (i=0;i<listElement.length;i++) { listElement[i].addEventListener('click',(function (i) { return function () { openURL(links[i]); }; }(i))); }
}
<li>Facebook</li><li>Twitter</li><li>Souncloud</li>

Adding Click Event Listeners During Iteration?

So a few things crosses my mind:

Firstly, edit_entry.bind(this, key);: Are you certain this is pointing to what you want? It should be pointing to the window object. Also, is there any reason to bind context for that particular function?

Secondly innerHTML: Generally it's discouraged to use innerHTML directly. I don't know how/when the browser layouts changes to innerHTML, the div might not be on the page when you call getElementById. As an alternative, you could try document.createElement("div"), set its properties accordingly and finally append it to lex_body.

Edit

From mdn:

Please note that using innerHTML to append html elements (e.g. el.innerHTML += "link") will result in the removal of any previously set event listeners. That is, after you append any HTML element that way you won't be able to listen to the previously set event listeners.

Adding addEventListener() in loop only works for last button

The main problem is that you redefine the HTML of adiv completely every time you iterate. This means that any event handler you had already bound to a child element of adiv is lost the moment you do adviv.innerHTML = .... Although you assign the same HTML plus some new one, you don't assign the event handlers that were previously defined. So they are lost.

Only the event handler you assign at the last iteration is not destroyed in this way.

Solution

A quick solution would be to first loop to create all the HTML, and then do a separate loop to assign the event handlers:

// First add all the new content:
var html = adiv.innerHTML;
for (var i = 0; i < array_length; ++i) {
var obj = data.Items[i];

html += "<div class='row'><div class='center-div six columns'>" + obj.Event + ", " + obj.Location + "</div></div>";
html += "<div class='row'><div class='center-div six columns'>" + obj.Date + ", " + obj.Time + "</div></div>";
html += "<div class='row'><div class='center-div six columns'><button id='yay_button_" + i + "' class='button-primary'>Deltag</button></div></div>";
}
adiv.innerHTML = html;

// Now bind the event handlers
// By using "let" instead of "var" the right value is retained
// in the handlers
for (let i = 0; i < array_length; ++i) {
var elem = document.getElementById('yay_button_' + i);
elem.addEventListener('click', function() {
alert('id: ' + i);
});
}

If your browser does not support ES2015 (for let), then you can use bind:

for (var i = 0; i < array_length; ++i) {
var elem = document.getElementById('yay_button_' + i);
elem.addEventListener('click', function(i) {
alert('id: ' + i);
}.bind(null, i));
}

adding 'click' event listeners in loop

You need to wrap the assignment of the event listener in a closure, something like:

var td;
for (var t = 1; t < 8; t++){
td = document.getElementById('td'+t);
if (typeof window.addEventListener === 'function'){
(function (_td) {
td.addEventListener('click', function(){
console.log(_td);
});
})(td);
}
}

Using addEventListener() in a for loop with various listeners

There are 3 issues with your code:

  1. In your for loop, you are essentially attaching strings as eventlisteners. You need to access your event listeners from the string you have.

Since you eventlisteners are declared in the global scopre, you can use window to access them:

button.addEventListener("click", window[listenerName]);

  1. You are attaching the event listeners before declaring them. You need to declare listener1 and so on before your for loop

  2. innerHtml does not exist. The right syntax is innerHTML

Here is a working example:

<!DOCTYPE html>
<html>
<body>

<button id="button-listener1">Try 1</button>
<button id="button-listener2">Try 2</button>
<button id="button-listener3">Try 3</button>
<button id="button-listener4">Try 4</button>

<p id="demo"></p>

<script>

var listener1 = function() {
document.getElementById('demo').innerHTML = "1";
}

var listener2 = function() {
document.getElementById('demo').innerHTML = "2";
}

var listener3 = function() {
document.getElementById('demo').innerHTML = "3";
}

var listener4 = function() {
document.getElementById('demo').innerHTML = "4";
}

var selector = "[id^=button]";
var allButtons = document.querySelectorAll(selector);
for (var button of allButtons) {
var listenerName = button.id.slice(button.id.lastIndexOf("-")+1);
button.addEventListener("click", window[listenerName]);
}
</script>

</body>
</html>

Loop through array and add event listener click to each

You should use addEventListener() as :

target.addEventListener(type, listener[, options]);

You could also get the index from forEach :

arr.forEach(function ( element_value,element_index ){ })

Hope this helps.

var sliders = [].slice.call(document.getElementsByClassName("sliderControlLi"));
sliders.forEach(function (element, index){ element.addEventListener("click", function(){ console.log("you clicked slider controler " +index + "!"); });});
<div class="sliderControlLi">slider 1</div><div class="sliderControlLi">slider 2</div><div class="sliderControlLi">slider 3</div><div class="sliderControlLi">slider 4</div>

How to loop through all the buttons to a click event listener

Adding a large number of event listeners will hinder your application's performance. Hence in such cases you can use the Event Delegation technique.
If you want to read more about this, I found this link very resourceful. In case you have any queries hit me up in the comments.

const input = document.querySelector("#user-input");
const table = document.querySelector("table");

table.addEventListener('click', (e) => {
//Since we only want to register button clicks inside the table and not any clicks on the blank space between the buttons.
if(e.target.tagName === "BUTTON") {
if(e.target.id === "clear") {
input.value = "";
} else {
input.value += e.target.value;
}
}
});
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Async JS</title>
<script src="promises.js" defer></script>
<style>
input {
margin-top: 10px;
}

table {
margin-bottom: 10px;
width: auto;
margin-top: 10px;
}
</style>
</head>

<body>
<main>
<input id="user-input">
<table>
<tr>
<td><button type="button" value="1" class="calc">1</button></td>
<td><button type="button" value="2" class="calc">2</button></td>
<td><button type="button" value="3" class="calc">3</button></td>
</tr>
<tr>
<td><button type="button" value="4" class="calc">4</button></td>
<td><button type="button" value="5" class="calc">5</button></td>
<td><button type="button" value="6" class="calc">6</button></td>
</tr>
<tr>
<td><button type="button" value="7" class="calc">7</button></td>
<td><button type="button" value="8" class="calc">8</button></td>
<td><button type="button" value="9" class="calc">9</button></td>
</tr>
<tr>
<td><button type="button" value="0" class="calc">0</button></td>
<td colspan="2"><button type="button" value="CLEAR" id="clear" class="calc">CLEAR</button></td>
</tr>
</table>
</main>
</body>

</html>


Related Topics



Leave a reply



Submit