Search code examples
javascriptasynchronousscrollevent-handlingweb-worker

Asynchronous scroll event issue. Pure JS


I am running JavaScript in a Web Worker with use of AMP script. There are two event listeners - mouseenter and mouseout. Both events work as supposed to, tooltipElem appears on mouse enter and disappears on mouse out. Here is my code:

    const button = document.querySelector('.tooltip-trigger');
    let tooltipElem;


    button.addEventListener("mouseenter", async function(event) {
    
        let target = event.target;

        let tooltipHtml = target.getAttribute('data-tooltip-text');
        if (!tooltipHtml) return;   

        tooltipElem = document.createElement('span');
        document.body.appendChild(tooltipElem);
        tooltipElem.innerHTML = tooltipHtml;

        /* ... */

    });


    button.addEventListener("mouseout", async function(event) {
    
        if (tooltipElem) {
            tooltipElem.remove();
            tooltipElem = null;
        }
        
    });

When scroll event fired tooltipElem is removed, but then I am unable to show it again on button element click. To make mouseenter work again I have to click at any other point on screen (feels like mouseout fixes it).

Doesn't work:

    document.addEventListener("scroll", async function(event) {
    
        if (tooltipElem) {
            tooltipElem.remove();
            tooltipElem = null;
        }   
        
    });

Tried to use interval, also doesn't work:

    var scrolling = false;

    document.addEventListener("scroll", async function() {
        scrolling = true;
    });

    setInterval( function() {
        if (scrolling) {
            scrolling = false;
            if (tooltipElem) {
                tooltipElem.remove();
                tooltipElem = null;
            }
        }
    }, 100 );

What can be wrong with my async scroll? Maybe event is not finished or memory leaks? No errors...

Here is a video, demonstrating scroll issue in the end (on second block). https://streamable.com/y53749


Solution

  • Figured out that the problem is in mouseenter event listener, so replaced it with click on touch devices and mouseenter on non-touch devices; Didn't managed to detect device in amp-script web worker using JS, so used Wordpress wp_is_mobile() function;

        <?php if ( wp_is_mobile() ) : ?>
        
        // Click (async)
        button.addEventListener("click", addTooltip, false);
        
        <?php else : ?>
    
        // Mouseover (async)
        button.addEventListener("mouseover", addTooltip, false);
        
        <?php endif; ?>