Search code examples
javascriptjquerylazy-loadingjquery-eventsevent-binding

How to simulate namespaced events or unbind individual events WITHOUT jQuery?


I have a framework that lazyloads ads when they are scrolled into the viewport. When the page loads, I check to see which are in view and load them. If they are not in view, I create a scroll event and I namespace each one so I can bind and unbind them individually:

if (adIsInView("ad1") == false) { 
    $(document).on("scroll.ad1", function() {
        if (adIsInView("ad1") == true) {
            displayAd("ad1");
            $(document).off("scroll.ad1");
        } 
    });
}

This way it's easy to set up scroll.ad1, scroll.ad2, etc., binding and unbinding them individually.

This is the only part of my code that is dependent on jQuery. I don't want to load a 50 KB file just so I can have namespaced events. How can I do this using addEventListener and removeEventListener? Obviously I can't just use

window.removeEventListener("scroll");

because this would unbind all of my scroll events, and namespacing ("scroll.ad1") doesn't exist natively.

I haven't found any other posts on this exact topic. I've heard a few people mention that the jQuery source code creates namespacing by storing events in an object, but I'm not exactly sure how that works. Any ideas?


Solution

  • You can bind and unbind specific handlers.

    if (adIsInView("ad1") == false) {
        var ad1_listener = function() {
            if (adIsInView("ad1") == true) {
                displayAd("ad1");
                window.removeEventListener("scroll", ad1_listener);
            } 
        }
        window.addEventListener("scroll", ad1_listener);
    }
    

    You can go a step further and do:

    function register_ad(ad) {
        function listener() {
            if (adIsInView(ad) === true) {
                displayAd(ad);
                window.removeEventListener("scroll", listener);
            } 
        }
        window.addEventListener("scroll", listener);
    }
    
    if (adIsInView("ad1") === false) {
        register_ad("ad1");
    }