Search code examples
javascriptfunctionclicklistenerstoppropagation

Clicking a button triggers an onClick() for the div, and stopPropagation only triggers once. Why only once?


I have a div element that when clicked, creates another div and a button. When clicked, the first div should create the second div (an overlay) and once the close button is pressed, the overlay should close. I want this process to be repeatable, but the problem I am currently facing is that it only works once.

IE: I click on the div, and an overlay with a button shows up. I click the button to close the overlay, and it goes away. Then I click on the div again, and again the overlay with a button shows up. But this time when I press the close button, it simply opens another overlay. How can I stop this from happening? I am at a loss, please help.

async function addClickListener2(div, imageName, tag) {
    div.addEventListener('click', async function () {  // closes on X button click, but opens again right away
        if (this.className === 'card loaded') {
            const overlay = document.createElement('div'); // create div 'overlay'
            const button = document.createElement('button');
            overlay.id = 'overlay'; // assign id for css
            div.appendChild(overlay); // append to clicked div so overlay isn't at top of page
            overlay.style.display = 'block'; // make overlay visible
            overlay.innerText = JSON.stringify(await getManifest(imageName, tag));
            button.id = 'overlayButton';
            button.innerText = 'X';
            overlay.appendChild(button);
            overlayCloseButton();
        }
    })
}

function overlayCloseButton() {
    document.getElementById('overlayButton').addEventListener('click', function (e) {
        e.stopPropagation(); // Only works once
        document.getElementById('overlay').style.display = 'none';
    })
}

Solution

  • In case this question will be useful to anyone else, I've solved the problem by simply deleting the overlay, instead of hiding it using .remove().

        div.addEventListener('click', async function () { 
            if (this.className === 'card loaded') {
                const pre = document.createElement('pre');
                const overlay = document.createElement('div'); // create div 'overlay'
                const button = document.createElement('button');
                overlay.id = 'overlay'; // assign id for css
                document.body.appendChild(overlay); 
                pre.innerText = JSON.stringify(await getManifest(imageName, tag), null, 2);
                button.id = 'overlayButton';
                button.innerText = 'X';
                overlay.appendChild(button);
                overlay.appendChild(pre);
                addOverlayCloseHandler();
            }
        })
    }
    
    function addOverlayCloseHandler() {
        document.getElementById('overlayButton').addEventListener('click', function (e) {
            document.getElementById('overlay').remove();
        })
    }