Search code examples
javascriptswiper.jselementor

Swiper instance not yet available on window.load


I need to setup the click event on an Elementor carousel widget, which is swiper.js 8 under the hood. Problem is, depending on the page (same code works elsewhere), not even when window.load executes the swiper instance is available to work with:

jQuery(window).on('load', function(){
    const swiperTarget = jQuery('#dp-neighborhoods .swiper');
    const swiperNeigh = swiperTarget.data('swiper');
    if (swiperNeigh) {
        alert('found it'); //it doesn't
        swiperNeigh.on('click', clickSwiper);
    }
    
    function clickSwiper(swiper, event) {...}

I can only get this to work if I call the function from a button, which is not ideal. A delay (Promise(resolve => setTimeout(resolve, time)) doesn't help either. Would there be another way to make this work?


Solution

  • Managed to solve this with an observer. Credit to Blaize Stewart

    function Observer(o, property){
        var _this = this;
        var value = o[property];
        this.observers = [];
        
        this.Observe = function (notifyCallback){
            _this.observers.push(notifyCallback);
        }
        
        Object.defineProperty(o, property, {
            set: function(val){
                _this.value = val;
                for(var i = 0; i < _this.observers.length; i++) _this.observers[i](val);
            },
            get: function(){
                return _this.value;
            }
        });
    
    }
    
    const swiperTarget = document.querySelector('#dp-neighborhoods .swiper'); 
    var observer = new Observer(swiperTarget, 'swiper');
    observer.Observe(function(newValue){
        const swiperNeigh = newValue;
        if (swiperNeigh) {
            swiperNeigh.on('click', clickSwiper);
        } 
    });