简体   繁体   中英

Click Event not working on dynamically created button

I am trying to create an interactive tutorial using an array of objects which contain a text for the current task.

The text creates the task and dynamically attaches a button.

let currentTutorialCount = 0;
var tutorial = [{
    text: "Welcome, I'll be your Task Manager and Guide <button class = 
   'button-next'> Got it</button>",
    set: function () {
      $('#info-container').addClass('non-active');
      $('#canvas-container').addClass('non-active');
      $('#info-container-transparent').css('display', 'block');
      $('#canvas-container-transparent').css('display', 'block');
      $('#suggestion').html(this.text);
    }
  },
  {
    text: "Here you can find information about your String and Current 
    State <button class = 'button-next'>Got it</button>",
    set: function () {
      $('#info-container-transparent').css('display', 'none');
      $('#info-container-text').addClass('highlightBorder');
      $('#info-container-buttons-transparent').css('display', 'block');
      $('#suggestion').html(this.text);
    }
  },
  {
    text: "Here you can generate new Random Graphs and Strings <button 
    class = 'button-next'>Got it</button>",
    set: function () {
      $('#info-container-text').removeClass('highlightBorder');
      $('#info-container-buttons').addClass('highlightBorder');
      $('#info-container-buttons-transparent').css('display', 'none');
      $('#info-container-buttons-transparent').css('display', 'block');
      $('#suggestion').html(this.text);
    }
  }
];` 

When I add the event listener on click on the button the plan is to move to the next task by increasing the currentTutorialCount and call the set function:

    $('.button-next').click(() => {
     currentTutorialCount += 1;
     tutorial[currentTutorialCount].set();
    });

The DOM structure is as follow:

<div id="main-feedback-grid">
  <div id="information">
    <p id="suggestion">Welcome, Make your first transition to the next node</p>
    <button class="answer" value="true">Yes</button>
    <button class="answer" value="false">No</button>
  </div>
</div>

My issue is that the click event only works when I click the button for the first time. I assume the reference of the button is lost every time the set() function creates a new one. Any suggestions ?

You're running into the classic issue of binding a click event to an element that is not present at runtime. When your script is being evaluated, the element .button-next is not yet present in the DOM, so the click event callback will not be bound to the button.

What you want is to rely on event bubbling: you want to listen on an element that is present at runtime, and see if the click event has bubbled from your dynamically-inserted button up to your static element.

Since the button is actually injected as a child node of #suggestion , and #suggestion is guaranteed to be present in the DOM at runtime, you can listen to the click event bubbling up to the #suggestion element instead:

$('#suggestion').on('click', '.button-next', () => {
  currentTutorialCount += 1;
  tutorial[currentTutorialCount].set();
});

A helpful tip: always select the closest possible static DOM element when binding your event listener. It is strongly discouraged to listen to bubbling evnets on document or body , because it is expensive (the JS engine has to iterate through all child nodes to find out which one emitted the event).

You can use like below:

$("body").find(".button-next").on('click', function(){
   // your code here
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM