ホームページ > 記事 > ウェブフロントエンド > 画像の遅延読み込みとjquery.lazyload.jsの使用例
画像の遅延読み込みはプロジェクトで使用されることがありますが、遅延読み込みの利点は何ですか?
主なポイントは 2 つあると思います。1 つ目は、多くの大きな画像を含む長いページの画像の読み込みを遅らせることで、ページの読み込みを高速化できるということです。2 つ目は、サーバーの負荷を軽減するためです。
以下では、一般的に使用される遅延読み込みプラグイン jquery.lazyload.js と遅延読み込みプラグインの実装方法を紹介します。
lazyload は、jQuery によって書かれた遅延読み込みプラグインです。ブラウザーの表示領域外の画像は、ユーザーがページをスクロールするまで読み込まれません。これは、画像のプリロードとまったく逆の方法で処理されるのと似ています。
まず、選択された img 要素は、実際の画像アドレスを表示するために img を処理するイベントにバインドされます。これにより、将来条件が満たされたときにイベントがトリガーされます。構成オブジェクト内のコンテナ属性構成。デフォルトでは window です。img 要素がコンテナ コンテナ ビューポート内にある場合、Appearance イベントがトリガーされます
img 要素がコンテナ コンテナ ビューポート範囲内にあるかどうかを判断するために、
$.belowthefold = function(element, settings) {}; // 在视口下方$.rightoffold = function(element, settings) {}; // 在视口右方$.abovethetop = function(element, settings) {}; // 在视口上方$.leftofbegin = function(element, settings) {}; // 在视口左方
data-original 属性には、実際の画像の URL パスが保存されます。
ヒント: CSS で画像の幅または高さを設定する必要があります。そうしないと、プラグインが正しく動作しない可能性があります。デフォルトでは、画像が画面に表示されるときにロードされます。しきい値オプションを設定して、しきい値を 200 に設定します。画面から 200 ピクセル離れると進みます。
<script src="jquery.js?1.1.11"></script><script src="jquery.lazyload.js?1.1.11"></script>読み込みをトリガーするイベントを設定します
<img class="lazy" data-original="img/example.jpg" width="640" height="480">$(function() { $("img.lazy").lazyload(); });
$("img.lazy").lazyload({ threshold : 200});
それだけです。ページが読み込まれてから 5 秒後に、画像の遅延読み込みを実行します。
画像が完全に読み込まれると、プラグインはデフォルトで show() メソッドを使用して画像を表示します。実際には、次のコードで使用する特殊効果を使用できます。フェードイン効果:
$("img.lazy").lazyload({ event : "click"});
JavaScript をサポートしていないブラウザの使用方法
$(function() { $("img.lazy").lazyload({ event : "sporty"}); }); $(window).bind("load", function() {var timeout = setTimeout(function() { $("img.lazy").trigger("sporty") }, 5000); });
$("img.lazy").lazyload({ effect : "fadeIn"});
JavaScript をサポートするブラウザでは、DOM の準備ができたらプレースホルダーを表示する必要があります。これはプラグインの初期化と同時に行うことができます。
<img class="lazy" data-original="img/example.jpg" width="640" heigh="480"><noscript><img src="img/example.jpg" width="640" heigh="480"></noscript>
遅延読み込み画像コンテナを設定します
.lazy { display: none; }
$("img.lazy").show().lazyload();
たとえば、プラグインを使用してリストをフィルタリングする場合、リスト内の各項目の表示ステータスを常に変更できます。パフォーマンスを向上させるため、Lazy Load Hidden イメージはデフォルトで無視されます。隠しイメージをロードする場合は、skip_invisible を false に設定します。
#container { height: 600px; overflow: scroll; } $("img.lazy").lazyload({ container: $("#container") });
ソースコード
$("img.lazy").lazyload({ failure_limit : 10});
$("img.lazy").lazyload({ skip_invisible : true});
/*! * Lazy Load - jQuery plugin for lazy loading images * * Copyright (c) 2007-2015 Mika Tuupola * * Licensed under the MIT license: * * * Project home: * * * Version: 1.9.7 * */ (function($, window, document, undefined) {var $window = $(window); $.fn.lazyload = function(options) {var elements = this;var $container;var settings = { threshold : 0, failure_limit : 0, event : "scroll", effect : "show", container : window, data_attribute : "original", skip_invisible : false, appear : null, load : null, placeholder : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"}; function update() {var counter = 0; elements.each(function() {var $this = $(this);if (settings.skip_invisible && !$this.is(":visible")) {return; }if ($.abovethetop(this, settings) ||$.leftofbegin(this, settings)) {/* Nothing. */} else if (!$.belowthefold(this, settings) && !$.rightoffold(this, settings)) { $this.trigger("appear");/* if we found an image we'll load, reset the counter */counter = 0; } else {if (++counter > settings.failure_limit) {return false; } } }); } if(options) {/* Maintain BC for a couple of versions. */if (undefined !== options.failurelimit) { options.failure_limit = options.failurelimit;delete options.failurelimit; }if (undefined !== options.effectspeed) { options.effect_speed = options.effectspeed;delete options.effectspeed; } $.extend(settings, options); } /* Cache container as jQuery as object. */$container = (settings.container === undefined || settings.container === window) ? $window : $(settings.container); /* Fire one scroll event per scroll. Not one scroll event per image. */if (0 === settings.event.indexOf("scroll")) { $container.bind(settings.event, function() {return update(); }); } this.each(function() {var self = this;var $self = $(self); self.loaded = false; /* If no src attribute given use data:uri. */if ($self.attr("src") === undefined || $self.attr("src") === false) {if ($self.is("img")) { $self.attr("src", settings.placeholder); } } /* When appear is triggered load original image. */$self.one("appear", function() {if (!this.loaded) {if (settings.appear) {var elements_left = elements.length; settings.appear.call(self, elements_left, settings); } $("<img />") .bind("load", function() { var original = $self.attr("data-" + settings.data_attribute); $self.hide();if ($self.is("img")) { $self.attr("src", original); } else { $self.css("background-image", "url('" + original + "')"); } $self[settings.effect](settings.effect_speed); self.loaded = true; /* Remove image from array so it is not looped next time. */var temp = $.grep(elements, function(element) {return !element.loaded; }); elements = $(temp); if (settings.load) {var elements_left = elements.length; settings.load.call(self, elements_left, settings); } }) .attr("src", $self.attr("data-" + settings.data_attribute)); } }); /* When wanted event is triggered load original image *//* by triggering appear. */if (0 !== settings.event.indexOf("scroll")) { $self.bind(settings.event, function() {if (!self.loaded) { $self.trigger("appear"); } }); } }); /* Check if something appears when window is resized. */$window.bind("resize", function() { update(); }); /* With IOS5 force loading images when navigating with back button. *//* Non optimal workaround. */if ((/(?:iphone|ipod|ipad).*os 5/gi).test(navigator.appVersion)) { $window.bind("pageshow", function(event) {if (event.originalEvent && event.originalEvent.persisted) { elements.each(function() { $(this).trigger("appear"); }); } }); } /* Force initial check if images should appear. */$(document).ready(function() { update(); }); return this; }; /* Convenience methods in jQuery namespace. *//* Use as $.belowthefold(element, {threshold : 100, container : window}) */ $.belowthefold = function(element, settings) {var fold; if (settings.container === undefined || settings.container === window) { fold = (window.innerHeight ? window.innerHeight : $window.height()) + $window.scrollTop(); } else { fold = $(settings.container).offset().top + $(settings.container).height(); } return fold <= $(element).offset().top - settings.threshold; }; $.rightoffold = function(element, settings) {var fold; if (settings.container === undefined || settings.container === window) { fold = $window.width() + $window.scrollLeft(); } else { fold = $(settings.container).offset().left + $(settings.container).width(); } return fold <= $(element).offset().left - settings.threshold; }; $.abovethetop = function(element, settings) {var fold; if (settings.container === undefined || settings.container === window) { fold = $window.scrollTop(); } else { fold = $(settings.container).offset().top; } return fold >= $(element).offset().top + settings.threshold + $(element).height(); }; $.leftofbegin = function(element, settings) {var fold; if (settings.container === undefined || settings.container === window) { fold = $window.scrollLeft(); } else { fold = $(settings.container).offset().left; } return fold >= $(element).offset().left + settings.threshold + $(element).width(); }; $.inviewport = function(element, settings) { return !$.rightoffold(element, settings) && !$.leftofbegin(element, settings) && !$.belowthefold(element, settings) && !$.abovethetop(element, settings); }; /* Custom selectors for your convenience. *//* Use as $("img:below-the-fold").something() or *//* $("img").filter(":below-the-fold").something() which is faster */ $.extend($.expr[":"], {"below-the-fold" : function(a) { return $.belowthefold(a, {threshold : 0}); },"above-the-top" : function(a) { return !$.belowthefold(a, {threshold : 0}); },"right-of-screen": function(a) { return $.rightoffold(a, {threshold : 0}); },"left-of-screen" : function(a) { return !$.rightoffold(a, {threshold : 0}); },"in-viewport" : function(a) { return $.inviewport(a, {threshold : 0}); },/* Maintain BC for couple of versions. */"above-the-fold" : function(a) { return !$.belowthefold(a, {threshold : 0}); },"right-of-fold" : function(a) { return $.rightoffold(a, {threshold : 0}); },"left-of-fold" : function(a) { return !$.rightoffold(a, {threshold : 0}); } }); })(jQuery, window, document);
htmlコード:
1、增加了图片预加载可选
2、修改了图片本身就在可视范围的时候直接显示而不需要滚动条触发
3、修改了Splice删除数组的时候,会跳过下一张图片BUG
4、浏览器窗口resize的时候图片出现也会加载
5、判断图片父层包裹顶部或者底部出现在可视范围内即可显示图片
var Lazy = { $:function(arg,context){var tagAll,n,eles=[],i,sub = arg.substring(1); context = context|| document;if(typeof arg =='string'){switch(arg.charAt(0)){case '#':return document.getElementById(sub);break;case '.':if(context.getElementsByClassName) return context.getElementsByClassName(sub); tagAll = Lazy.$('*'); n = tagAll.length;for(i = 0;i<n;i++){if(tagAll[i].className.indexOf(sub) > -1) eles.push(tagAll[i]); }return eles;break;default:return context.getElementsByTagName(arg);break; } } }, getPos:function (node) {var scrollx = document.documentElement.scrollLeft || document.body.scrollLeft, scrollt = document.documentElement.scrollTop || document.body.scrollTop;var pos = node.getBoundingClientRect();return {top:pos.top + scrollt, right:pos.right + scrollx, bottom:pos.bottom + scrollt, left:pos.left + scrollx } }, bind:function(node,type,handler){ node.addEventListener?node.addEventListener(type, handler, false):node.attachEvent('on'+ type, handler); }, unbind:function(node,type,handler){ node.removeEventListener?node.removeEventListener(type, handler, false):node.detachEvent('on'+ type, handler); }, toArray:function(eles){var arr = [];for(var i=0,n=eles.length;i<n;i++){ arr.push(eles[i]); }return arr; } };function imgLazyLoad(){var timer,screenHeight = document.documentElement.clientHeight;// 选择所有图片var allimg = Lazy.$('img');// 筛选CLASS为lazyload的图片var elems = Lazy.$('.lazyload',allimg);// 转换为真正的数组elems = Lazy.toArray(elems);if(!elems.length) return;// 没有发生滚动事件时如果图片在可视范围之内,也显示for(var i = 0;i < elems.length;i++){// 获取图像的父元素即包裹图像的元素,判断图像是否在可视区域即直接判断父元素是否可视var parent = elems[i].parentNode;var pos = Lazy.getPos(parent);var posT = pos.top;var posB = pos.bottom;// 没有滚动条情况如果距离顶部的距离小于屏幕的高度则赋值SRCif(posT < screenHeight){ elems[i].src = elems[i].getAttribute('data-img');// 移除后,数组的长度减一,下一个下标需减一elems.splice(i--,1); } }// 绑定scroll事件Lazy.bind(window,'scroll',loading); Lazy.bind(window,'resize',loading);function loading(){ timer && clearTimeout(timer); timer = setTimeout(function(){var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; screenHeight = document.documentElement.clientHeight;for(var i = 0;i < elems.length;i++){var parent = elems[i].parentNode;var pos = Lazy.getPos(parent);var posT = pos.top;var posB = pos.bottom;var screenTop = screenHeight+scrollTop;// 元素顶部出现在可视区 或者 元素底部出现在可视区if((posT > scrollTop && posT < screenTop) || (posB > scrollTop && posB < screenTop)){ elems[i].src = elems[i].getAttribute('data-img'); elems.splice(i--,1); }else{// 去掉以下注释开启图片预加载// new Image().src = elems[i].getAttribute('data-img'); } }if(!elems.length){ Lazy.unbind(window,'scroll',loading); Lazy.unbind(window,'resize',loading); } },300); } } imgLazyLoad();
1、在图片上增加lazyload的类(class='lazyload')
2、把真实的图片地址放入自定义属性data-img 中,把图片的SRC属性设置为一个一像素的透明图片,图片需要设置width,height属性,以免布局混乱
如下:
<img data-img="a.jpg" src="loading.gif" width="640" height="480" class='lazyload'>
3、在需要延迟加载的页面调用imgLazyLoad()函数;
该原生js实现的懒加载转载地址:
以上が画像の遅延読み込みとjquery.lazyload.jsの使用例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。