weixin_39832348
weixin_39832348
2020-11-30 07:57

Lazy load

Why dont you create a lazy load function? Like a royal slider.

该提问来源于开源项目:sachinchoolur/lightslider

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

9条回答

  • weixin_39588265 weixin_39588265 4月前

    I've also made some small changes, mostly to lazy load thumbnails, too

    javascript
    
        <li data-thumb="//:0#$Bild.ScaleWidth(300).Link">
                 <img data-src="$Bild.ScaleWidth(900).Link" src="//:0">
        </li>
    
    javascript
        var thumbItem = 3
    
        $('.lightslider-project-gallery').lightSlider({
            gallery: true,
            item: 1,
            vertical: true,
            adaptiveHeight: true,
            thumbItem: thumbItem,
            thumbMargin: 20,
            slideMargin: 0,
            loop: false,
            onBeforeStart: function($el) {
                $el.find('li img').slice(0, 3).each(function(index, el) {
                    $(el).attr('src', $(el).attr('data-src'));
                    $(el).css('display', 'initial')
                });
            },
            onSliderLoad: function($el) {
                var eqText = "";
                for(var i = 0; i < thumbItem + 1; i++) {
                    if(i != 0) eqText += ",";
                    eqText += ":eq(" + i + ")";
                }
    
                $el.parent().parent().find('.lSPager img').filter(eqText).each(function(index, el) {
                    $(el).attr('src', $(el).attr('src').replace('//:0#', ''));
                    $(el).css('display', 'initial')
                });
            },
            onAfterSlide: function($el, scene) {
                $el.find('img').filter(':eq(' + ($el.getCurrentSlideCount() - 1) + '), :eq(' + $el.getCurrentSlideCount() + ')').each(function(index, el) {
                    $(el).attr('src', $(el).attr('data-src'));
                    $(el).css('display', 'initial')
                });
    
                var eqText = "";
                for(var i = 0; i < thumbItem - 1; i++) {
                    if(i != 0) eqText += ",";
                    eqText += ":eq(" + ($el.getCurrentSlideCount() + i) + ")";
                }
    
                $($el).parent().parent().find('.lSPager img').filter(eqText).each(function(index, el) {
                    $(el).attr('src', $(el).attr('src').replace('//:0#', ''));
                    $(el).css('display', 'initial')
                });
            }
    
    点赞 评论 复制链接分享
  • weixin_39718006 weixin_39718006 4月前

    Tried out 's solution and works fine. Also tried -perl's, but unfortunately it didn't work reliably: when jumping pictures on the thumbnail slider, sometimes the chosen picture didn't show up, hmm...

    Made a small change to 's solution to prevent broken image icons to be shown when jumping pictures on the thumbnail slider and passing pictures haven't been loaded yet:

    <img data-src="{{ $photo->present()->photoUrl() }}" src="//:0" style="display:none"/>

    javascript
    $('#image-gal').lightSlider({
        //LAZY LOADING
        onBeforeStart: function($el) {
            var src_img = $el.find('li img').first().attr('data-src');
            var $img = $el.find('li img').first();
            $img.attr('src', src_img);
            $img.css('display', 'initial');
        },
        onSliderLoad: function($el) {
            $('.lSPrev').hide();
        },
        onAfterSlide: function($el, scene) {
            var $img = $el.find('img').eq($el.getCurrentSlideCount() - 1);
            var $img_src = $img.attr('data-src');
            $img.attr('src', $img_src);
            $img.css('display', 'initial');
            if ($el.getCurrentSlideCount() == 1) {
                $('.lSPrev').hide();
            } else if ($el.getCurrentSlideCount() == $el.find('li').length) {
                $('.lSNext').hide();
            } else {
                $('.lSPrev').show();
                $('.lSNext').show();
            }
        },
        gallery: true,
        item: 1,
        loop: false,
        slideMargin: 0,
        thumbItem: 4,
        keyPress: true
    });
    
    点赞 评论 复制链接分享
  • weixin_39616503 weixin_39616503 4月前

    For those who visit and wondering why the previous solution wants loop: false .. You can technically leave loop set to true but when you do and begin swiping or using the nav arrows to navigate LEFT (when on the first slide to navigate backwards) you will see a flash/pop of the image. This flashing doesnt occur if you navigate RIGHT after the last slide. It just seems to happen only when going backwards past the first slide.

    If you dont like that flashing thing you can prevent the user from navigating/swiping left (while on the first slide) by setting Loop to false, as the solution did above, but doing so will prevent the slide from restarting from the beginning after it gets to the last slide. To create an endless-pseudo loop just add the following lines under onAfterSlide:

    
    if (slider.getCurrentSlideCount()===slider.find('li').length)
       tim=setTimeout(function(){slider.goToSlide(1);},1500); // change 1500 to the delay in milliseconds
    else
       clearTimeout(tim);
    

    dont forget to add var tim; as a global variable.

    点赞 评论 复制链接分享
  • weixin_40004057 weixin_40004057 4月前

    -perl Thanks, your code worked perfectly for us!

    +1 this should be in the core lightSlider code though.

    点赞 评论 复制链接分享
  • weixin_39631350 weixin_39631350 4月前

    I've modified laimisf script a bit to always load the current image and the next one.

    php
        $('#image-gal').lightSlider({
            gallery: true,
            item: 1,
            loop: false,
            slideMargin: 0,
            thumbItem: 4,
            keyPress: true,
    
            //LAZY LOADING
            onBeforeStart: function (slider) {
                for (var i = 1; i <= 2; i++) {
                    var img = slider.find('li:nth-child(' + i + ') img');
                    img.attr('src', img.attr('data-src'));
                }
            },
            onSliderLoad: function (slider) {
                $('.aboutSliderHidden').removeClass('aboutSliderHidden');
                slider.parent().find('.lSPrev').hide();
            },
            onAfterSlide: function (slider, scene) {
                for (var i = 0; i <= 1; i++) {
                    var img = slider.find('img').eq(slider.getCurrentSlideCount() + i);
                    img.attr('src', img.attr('data-src'));
                }
    
                var lsPrev = slider.parent().find('.lSPrev');
                var lsNext = slider.parent().find('.lSNext');
    
                if (slider.getCurrentSlideCount() === 1) {
                    lsPrev.hide();
                }
                else if (slider.getCurrentSlideCount() === slider.find('li').length) {
                    lsNext.hide();
                }
                else {
                    lsPrev.show();
                    lsNext.show();
                }
            }
        });
    
    点赞 评论 复制链接分享
  • weixin_39626690 weixin_39626690 4月前

    My solution. Loop must be off. If it's left, the solution will not work!

    I've added data-src atribute to img:

    html
    <img data-src="{{ $photo->present()->photoUrl() }}" src="//:0">
    

    Then, my lightslider initialization looks like this:

    javascript
    //initializes image gallery
            $('#image-gal').lightSlider({
                //LAZY LOADING
                onBeforeStart: function ($el) {
                    var src_img = $el.find('li img').first().attr('data-src');
                    $el.find('li img').first().attr('src', src_img);
                },
                onSliderLoad: function ($el) {
                    $('.lSPrev').hide();
                },
                onAfterSlide: function ($el, scene) {
                    var $img = $el.find('img').eq( $el.getCurrentSlideCount()-1 );
                    var $img_src = $img.attr('data-src');
                    $img.attr('src', $img_src);
    
                    if ($el.getCurrentSlideCount() == 1)
                    {
                        $('.lSPrev').hide();
                    }
                    else if ($el.getCurrentSlideCount() == $el.find('li').length)
                    {
                        $('.lSNext').hide();
                    }
                    else
                    {
                        $('.lSPrev').show();
                        $('.lSNext').show();
                    }
                },
    
                gallery: true,
                item: 1,
                loop: false,
                slideMargin: 0,
                thumbItem: 4,
                keyPress: true
            });
    
    点赞 评论 复制链接分享
  • weixin_39832348 weixin_39832348 4月前

    Its because first and last "li" are "clone" elements, when we call them, they jump to the correct "li". A correct solution is create a function and call in this momment, but: my lazy solution is:

    onAfterSlide: function (el) { setTimeout(function(){var src_img = el.find('li.active img').attr('data-src'); el.find('li.active img').attr('src', src_img)},500); }

    点赞 评论 复制链接分享
  • weixin_39865952 weixin_39865952 4月前

    your solution is great, but I see a bug when sliding from the first to the last slide (to the left). It updates li.active img src with data-img, but then immediately changes back to the placeholder src - did you experience the same?

    点赞 评论 复制链接分享
  • weixin_39832348 weixin_39832348 4月前

    I did it:

    onSliderLoad: function (el) { var src_img = el.find('li img').first().attr('data-img'); el.find('li img').first().attr('src', src_img);

    }, onAfterSlide: function (el) { console.log(el); var src_img = el.find('li.active img').attr('data-img'); el.find('li.active img').attr('src', src_img) }

    点赞 评论 复制链接分享