Hey guys I have to create a few buttons which redirect to a different URL, but I get the list of URL’s from an API so the amount of buttons periodically changes.
Basically I have this bit of code right now:
// Sample data with fake URLs var result = ["foo.com", "bar.com", "baz.com"]; var buttDiv = document.getElementById("buttonsHeader"); for(var b in result["buttons"]) { var nButton = document.createElement("button"); nButton.innerHTML = result["buttons"][b] nButton.addEventListener("click", function(){ buttonRedir(result["buttons"][b]); }); buttDiv.appendChild(nButton); }
which is calling buttonRedir()
, which is pretty simple and looks like this:
function buttonRedir(link) { console.log(link) window.open( "https://" + link, '_blank' ) }
This works fine and creates the correct number of buttons which call the right OnClick() function. The problem is that all of the buttons will call buttonRedir
with the last URL (so in this case “baz.com”) instead of the correct address.
I’ve come across a few questions that seem to point me in the right direction but I haven’t been able to get it working yet. I’ve tried things like making sure my formatting was correct, setting the ID of the element, or just storing data on the DOM element itself.
I’m also pretty much entirely restricted to Vanilla JS due to some corporate policies, but I feel like I shouldn’t need anything else.
Advertisement
Answer
The reason is your event handler referred to result[buttons][b] which equals the last item by the time the handler is invoked.
The solution is to pass the value instead of the reference to that value. This is done by passing it to a function (which is called an IIFE).
Now when buttonRedir(link);
is invoked, link
equals the correct value.
var result = { buttons: ["foo.com", "bar.com", "baz.com"] }; var buttDiv = document.getElementById("buttonsHeader"); for (var b in result["buttons"]) { var nButton = document.createElement("button"); nButton.innerHTML = result["buttons"][b]; (function(link) { nButton.addEventListener("click", function() { buttonRedir(link); }); })(result["buttons"][b]); buttDiv.appendChild(nButton); } function buttonRedir(link) { console.log(link) window.open( "https://" + link, '_blank' ) }
<div id="buttonsHeader"></div>