0

I recently began to code on a small frontend project in javascript. I came across the following problem:

Code Part 1

const startFeed = document.getElementById('startFeedButton');
const stopFeed = document.getElementById('stopFeedButton');

startFeed.addEventListener("click", () => {
    api.streamingFunction(callback(response){
        appendResponseToDom(response);
    }
}

stopFeed.addEventListener("click", () => {
    endStreamingFunction();
}

The 'api.streamingFunction' is part of a library and streams data via websocket. The 'callback' gets repeatedly called every time new data is available. It'll let you do something with the data inside the callback function. 'endStreamingFunction' closes the websocket. Now the 'appendResponseToDom' function takes a piece of the data and appends it to the Dom like so:

Code Part 2

const someWhereInDom = document.getElementById('somewhere'); 

function appendResponseToDom(apiData) {
    const newHTML = document.createElement("div");
    newHTML.innerHTML = `
        <div class="data">${apiData}</div>
        <button id=${runningIndex}>Click here</button>
    `
    someWhereInDom.appendChild(newHTML);
}

Each button has a running index to uniquely select it. I didn't specify how runningIndex is evaluated in the code above.

What I want to do now is:

  • select every button uniquely after the newHTML has been inserted into the Dom (by adding event listeners) (and optionally in parallel stream new data via websocket)

Is this possible ? How would I usually do that ? Maybe you can point me in the right direction, thanks.

p4rch
  • 163
  • 8
  • Do they all have the same parent element? If so -> [Event delegation](https://stackoverflow.com/a/1688293/402037) – Andreas Apr 04 '18 at 11:25
  • If you are using jQuery, there is a very easy way to add listeners to all elements one single time, even if they are added after the load. Maybe the answers from here could help: https://stackoverflow.com/questions/16512016/event-listener-in-elements-appended-after-dom-content-loaded – Calvin Nunes Apr 04 '18 at 11:40
  • Tried it, but it doesn't seem to work. I think the problem lies somehow in the api function. Will further elaborate on it, thanks – p4rch Apr 04 '18 at 12:31

1 Answers1

1

Solved it by observing changes in the Dom. See here: MutationObserver.

This article was also helpful: Detect, Undo And Redo DOM Changes With Mutation Observers

Solution Code

const mutationObserver = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
    if(mutation.target.nodeName === "BUTTON") {
      mutation.target.addEventListener("click", () => {
        console.log("clicked " + mutation.target.className); //Now, I can do sth with it! 
      })
    }
  });
});

mutationObserver.observe(someWhereInDom, {
  attributes: true,
  childList: true
});
p4rch
  • 163
  • 8