0

Well I wanna ask something about replaceChild in here and I was got trouble when I used that function, so the problem is when I have some function addEventListener on my button, when I was replace the old button to new element then bring back again, my event listener on my old button doesn't work like before, any suggest to keep my event listener work on my button when my button was replace? Oh ya in bellow I will give you all the link of example of my problem, you can access to understand more about my problem, thanks before have a nice day!

I'll put my code in bellow :

const button = document.querySelectorAll('.button');

button.forEach(function (element) {
    element.addEventListener('click', function () {
    const buttonClass = element.classList;
    
    if (buttonClass.contains('custom')) {
        const buttons = document.querySelector('.buttons');
      const testElement = document.createElement('p');
        testElement.innerHTML = "I'm Paragraph"
      
      buttons.replaceChild(testElement, buttons.lastElementChild);
    } else {
        const buttons = document.querySelector('.buttons');
      const customElement = document.createElement('button');
        customElement.className = "button custom"
        customElement.innerHTML = "5"
        
      buttons.replaceChild(customElement, buttons.lastElementChild);
    }
  });
});

document.querySelector('.custom').addEventListener('click', function () {
    console.log('you touched me!')
});
<div class="buttons">
  <button class="button">1</button>
  <button class="button">2</button>
  <button class="button">3</button>
  <button class="button">4</button>
  <button class="button custom">5</button>
</div>
ProLuck
  • 331
  • 4
  • 18
  • 4
    You can use a trick called [event delegation](https://stackoverflow.com/questions/1687296/what-is-dom-event-delegation). – Reyno Mar 28 '22 at 06:54
  • @Teemu, I already put that on the link question description sir – ProLuck Mar 28 '22 at 06:58
  • @Reyno thanks for the advice sir, maybe I'll try for your suggest and comeback here again when I got some problem – ProLuck Mar 28 '22 at 06:58

2 Answers2

3

Use event delegation: listen for the click on a container element. These click events bubble up, so even when a new button generates the event, it will bubble up to the container you are listening on.

You can do the same for the buttons that don't get replaced, so your code remains together, and you don't have to iterate the buttons.

Adapted code:

const buttons = document.querySelector('.buttons');

// Listen on a container element -- could even be body
// Grab the event argument
document.querySelector('.buttons').addEventListener('click', function (e) {
    // Then check whether the source of the event was our button
    const buttonClass = e.target.classList;
    if (buttonClass.contains("custom")) {
        console.log('you touched me!');
        const testElement = document.createElement('p');
        testElement.innerHTML = "I'm Paragraph";
        buttons.replaceChild(testElement, buttons.lastElementChild);
    } else {
        const customElement = document.createElement('button');
        customElement.className = "button custom";
        customElement.innerHTML = "5";
        buttons.replaceChild(customElement, buttons.lastElementChild);
    }
});
<div class="buttons">
  <button class="button">1</button>
  <button class="button">2</button>
  <button class="button">3</button>
  <button class="button">4</button>
  <button class="button custom">5</button>
</div>
trincot
  • 317,000
  • 35
  • 244
  • 286
  • thanks for the advice sir, but why when I tried to use this when I click the last button on my parent element which is number 5 my paragraph doesn't show and replace the last element button? – ProLuck Mar 28 '22 at 07:15
  • Your code never added the paragraph element on the page. I have added this to my answer now, although I don't exactly know what you expected this paragraph to *replace*? – trincot Mar 28 '22 at 07:16
  • 1
    I did sir, in the first condition when I got true condition, but at least your advice is work sir, thank you so much, have a nice day. I try to change a little bit your code to mine like this `document.body.appendChild(testElement); // You wanted to add this?` to `buttons.replaceChild(testElement, buttons.lastElementChild);` – ProLuck Mar 28 '22 at 07:22
  • Yes, indeed you did -- that original line of code I missed is now also back in my answer. Note that when you click the paragraph, it also will add the button again. If this is not what you want, then you need to adjust this code a bit. – trincot Mar 28 '22 at 07:26
1

When you bring back the element, that means you are adding the new element to the HTML DOM. In this case, again, you have to bind that element with the eventListener. I would suggest use classes to bind the event and delegate or removeEventListner and rebind it whenever you bring back the element to the DOM.

Firoz Tennali
  • 334
  • 3
  • 14
  • Hi @Firoz Tennali, thanks for the advice sir, but can you give me some example or the link to getting more information about you said? I still confused about this and this for the first time for me move to vanilla javascript, thanks – ProLuck Mar 28 '22 at 07:06