Skip to content
Advertisement

Creating multiple buttons with different onclick() events

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>
User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement