Skip to content

I coded lazy loading for videos, background images and images but it didn’t work on safari

I coded lazy loading for videos, background images and images but didn’t work on ios safari.

I want show the background images/images/video with IntersectionObserver method.

below codes are for background image and video.

<a href="#" id="comp-modal1" data-toggle="modal" data-target="#vidmodal" class="col-12 col-sm-3 align-self-center show-bkg lazy-bg lazy" 
        data-video="{{ get_template_directory_uri() . $video_path . $qt190}}"
        data-srcset="{{ get_template_directory_uri() }}/assets/images/vid-images/show-bk.jpg" aria-label="background">
            <div class="show-info">
                <i class="fa fa-play-circle fa-3x" aria-hidden="true"></i>
                <h3>QTech QT190 Journey</h3>
            </div>
        </a>

<video data-src="/wp-content/uploads/2019/03/Aristospray-QTech-Q5-2-minute-montage-v3-android-pad-compress.mp4"
    poster="{{ get_template_directory_uri() }}/assets/images/vid-images/pistol-suction.jpg"
    width="100%" height="auto"  
    class="lazy" 
    aria-label="video" 
    data-id="vid1">
    </video>

and this is my JS =


    const lazy ={
        img:(img)=>{
            img.src = img.dataset.src;
        },
        background:(bg)=>{
            bg.style.backgroundImage = `url(${bg.dataset.srcset})`;
        },
        video:(vid)=>{
            vid.load();
            fetchVideoAndPlay(vid);
        },
    }
    
    
    function fetchVideoAndPlay(video){
        const preloadHolder = (document.querySelector(`#${video.dataset.id}`));
        //console.log(video.dataset.src);
        fetch(video.dataset.src)
        .then(response=> {
            video.setAttribute('data-src','');
            return response.blob();
            })
        .then(blob=>{
            video.src = URL.createObjectURL(blob);
            video.muted = true;
            preloadHolder.remove();
            return video.play();
        })
        .then(()=>{
            console.log('Played');
        })
        .catch( (e)=>{
            console.error(e);
        });
    }
    
    
    
    const lazyItems = [].slice.call(document.querySelectorAll('.lazy'));
    const configInterSection = {root: null,rootMargin: '0px',threshold: [0]};

    if ('IntersectionObserver' in window) {         
        let lazyObserver = new IntersectionObserver(function(entries){ 
            // fire lazy loading
            entries.forEach(function(item) {
                if (item.isIntersecting) {
                    
                    if(item.target.ariaLabel == 'background') lazy.background(item.target);
                    if(item.target.ariaLabel == 'image') lazy.img(item.target);
                    if(item.target.ariaLabel == 'video') lazy.video(item.target);
                    
                    // remove & add classes
                    item.target.classList.remove('lazy');
                    item.target.classList.add('lazy-loaded');
                    
                    //unboud
                    lazyObserver.unobserve(item.target);
                }
            });
        }, configInterSection);
        
        if(Array.isArray(lazyItems)){
            lazyItems.forEach(function(lazy) {
                lazyObserver.observe(lazy);
            });
        }   
        
    }

-Is there a way to modify this code in ios Safari?

  • Also this codes didn’t work on the Firefox.

Answer

item.target.ariaLabel is availbale in v8 engine (chrome). hence I changed it to item.target.getAttribute('aria-label')

now it works.