Issue was with closures.
See SO - Closures and MDN - Closures with thanks to @Arun-P-Johny
Question
I've been rewriting my Chrome Extension in vanilla code rather than jQuery, and for the most part it's been easy. I have however come across a part that doesn't work as intended.
Original jQuery-based code:
$(".content .flair").click(function(){
//Irelevant code using "this"
});
New Vanilla-only code:
var flairs = document.querySelectorAll(".content .flair");
for (var i = 0; i < flairs.length; i++){
flairs[i].addEventListener("click", function(event){
//Irrelevant code using flairs[i]
});
}
The issue with the vanilla code is that every click on a .content .flair
element always uses information from the last element in flairs
(i.e. flairs[flairs.length - 1]
rather than using flairs[i]
.
I just can't squash this bug!
La solution
Issue was with closures.
See SO - Closures and MDN - Closures with thanks to @Arun-P-Johny
Autres conseils
A great option for dealing with this is to turn your DOM element list into a proper Array using slice:
var buttonElementList = document.querySelectorAll('button');
// not a real array, so .forEach will not work
var buttonElementArray = Array.prototype.slice.call(buttonElementList);
// returns an array, can call .forEach or .map (or use .length)