目录javascript
Lazy Load也叫惰性加载,延迟加载,顾名思义,就是在图片未到达可视区域时,不加载图片,咱们经常在不少的优秀网站上看到相似的例子,例如迅雷、土豆、优酷等,因为一个网页的图片很是多,一次性加载增长服务器压力,并且用户未必会拉到底部,浪费用户流量,Lazy Load采用按需加载,更快的加载速度从而达到优化网页的目的。css
使用方法:html
<script src="jquery.js" type="text/javascript"></script>
<script src="jquery.lazyload.js" type="text/javascript"></script>
<img class="lazy" data-original="img/example.jpg" width="640" height="480">
$(function(){ $("img.lazy").lazyload(); });
注意:你必须给图片设置一个height和width,或者在CSS中定义,不然可能会影响到图片的显示。前端
$("img.lazy").lazyload({ threshold :200 });
事件绑定加载的方式:event,你可使用jQuery的事件,例如“click”、“mouseover”,或者你也能够自定义事件,默认等待用户滚动,图片出如今可视区域。下面是使用click:java
$("img.lazy").lazyload({event:"click"});
显示效果:effect,默认使用show(),你可使用fadeIn(逐渐出现)方式,代码以下:jquery
$("img.lazy").lazyload({ effect :"fadeIn" });
对于禁用javascript的浏览器则要加上noscript内容:css3
<img class="lazy" data-original="img/example.jpg" width="640" heigh="480"> <noscript><img src="img/example.jpg" alt="jQuery图片预加载(延迟加载)插件Lazy Load" width="640" heigh="480"></noscript>
图片限定在某个容器内:container,你能够经过限定某个容器内容的图片才会生效,代码以下:web
#container {
height:600px;
overflow: scroll;
}
$("img.lazy").lazyload({ container: $("#container") });
原文连接: jQuery图片预加载(延迟加载)插件Lazy Loadajax
在浏览器渲染图片的时候, 它得到图片的一片区域的时候, 就已经为这张图片预留了一片空白的区域来填充图片, 这就是预加载得到图片尺寸最原始的使用方法.数组
有时候会加载一些在当前页面没有用到的图片,是为了提早加载到缓存里,这样后面的页面就能够直接从缓存读取了。
加载大图的时候,咱们能够先显示模糊的缩略图,等到大图加载完了,再把缩略图替换掉,这样填补了图片加载期间的空白时间。
image也有onload和onerror事件,分别是加载完后和加载失败时执行。
Image对象是专门用于处理图片加载的,就至关于内存中的img标签。
图片预加载案例:鼠标移入一张图片时,换成另外一张图片,移出时换回原来的图片。正常作法是,鼠标移入的时候,改变图片的src,但这时就要去加载图片了,会等待一段时间,这样体验很差。预加载的作法是,在页面加载完,鼠标移入以前就经过Image对象把图片加载进缓存了,这样鼠标移入的时候直接从缓存里读取了,速度很快。
if(document.images){ var img = new Image(); img.src = "img/example.jpg"; }
//实现图片的预加载 function preloadImg(srcArr){ if(srcArr instanceof Array){ for(var i=0; i<srcArr.length; i++){ var oImg = new Image(); oImg.src = srcArr[i]; } } } //预加载图片 preloadImg(['image/example.jpg']); //参数是一个url数组
function getPreloadImgAttr(url,callback){ var oImg = new Image(); //建立一个Image对象,实现图片的预加载 oImg.src = url; // 看下一节,其实应当先进行onload的绑定,再赋值给src if(oImg.complete){ //若是图片已经存在于浏览器缓存,直接调用回调函数 callback.call(oImg); return; //直接返回,再也不处理onload事件 } oImg.onload = function(){ //图片下载完毕时异步调用callback函数 callback.call(oImg); }; } getPreloadImgAttr('image/example.jpg',function(){ console.log(this.width, this.height); });
建立了一个临时匿名函数来做为图片的onload事件处理函数,造成了闭包。
相信你们都看到过ie下的内存泄漏模式的文章,其中有一个模式就是循环引用,而闭包就有保存外部运行环境的能力(依赖于做用域链的实现),因此img.onload这个函数内部又保存了对img的引用,这样就造成了循环引用,致使内存泄漏。(这种模式的内存泄漏只存在低版本的ie6中,打过补丁的ie6以及高版本的ie都解决了循环引用致使的内存泄漏问题)。
只考虑了静态图片的加载,忽略了gif等动态图片,这些动态图片可能会屡次触发onload。
function loadImage(url, callback) { var img = new Image(); //建立一个Image对象,实现图片的预下载 img.onload = function(){ img.onload = null; callback(img); } img.src = url; }
这样内存泄漏,动态图片的加载问题都获得了解决,并且也以统一的方式,实现了callback的调用。
关于这个方法, 有个疑问是缓存的问题, 在原文里也给出了一些解释
通过对多个浏览器版本的测试,发现ie、opera下,当图片加载过一次之后,若是再有对该图片的请求时,因为浏览器已经缓存住这张图片了,不会再发起一次新的请求,而是直接从缓存中加载过来。对于 firefox和safari,它们试图使这两种加载方式对用户透明,一样会引发图片的onload事件,而ie和opera则忽略了这种同一性,不会引发图片的onload事件,所以上边的代码在它们里边不能得以实现效果。
但总体来说,仍然应该先进行onload事件的绑定, 再赋值src
参考:[前端] 图片预加载及获取属性 关于图片的预加载,你所不知道的
这个概念就是写一个CSS样式设置一批背景图片,而后将其隐藏,这样你就看不到那些图片了。那些背景图片就是你想预载的图片。
#preload-01 { background: url(http://domain.tld/image-01.png) no-repeat -9999px -9999px; } #preload-02 { background: url(http://domain.tld/image-02.png) no-repeat -9999px -9999px; } #preload-03 { background: url(http://domain.tld/image-03.png) no-repeat -9999px -9999px; }
这里为了隐藏这些图片, 使用了位置设置为极大的负值的方法. 还能够直接设置 { width: 0; height: 0; display: none};
该方法虽然高效,但仍有改进余地。使用该法加载的图片会同页面的其余内容一块儿加载,增长了页面的总体加载时间。为了解决这个问题,咱们增长了一些JavaScript代码,来推迟预加载的时间,直到页面加载完毕。代码以下:
// better image preloading @ <a href="http://perishablepress.com/press/2009/12/28/3-ways-preload-images-css-javascript-ajax/">http://perishablepress.com/press/2009/12/28/3-ways-preload-images-css-javascript-ajax/</a> function preloader() { if (document.getElementById) { document.getElementById("preload-01").style.background = "url(http://domain.tld/image-01.png) no-repeat -9999px -9999px"; document.getElementById("preload-02").style.background = "url(http://domain.tld/image-02.png) no-repeat -9999px -9999px"; document.getElementById("preload-03").style.background = "url(http://domain.tld/image-03.png) no-repeat -9999px -9999px"; } } function addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { if (oldonload) { oldonload(); } func(); } } } addLoadEvent(preloader);
在该脚本的第一部分,咱们获取使用类选择器的元素,并为其设置了background属性,以预加载不一样的图片。
该脚本的第二部分,咱们使用addLoadEvent()函数来延迟preloader()函数的加载时间,直到页面加载完毕。
若是JavaScript没法在用户的浏览器中正常运行,会发生什么?很简单,图片不会被预加载,当页面调用图片时,正常显示便可。
参考: 纯CSS图片预加载 Javascript图片预加载详解
该方法利用DOM,不只仅预加载图片,还会预加载CSS、JavaScript等相关的东西。使用Ajax,比直接使用JavaScript,优越之处在于JavaScript和CSS的加载不会影响到当前页面。该方法简洁、高效。
window.onload = function() { setTimeout(function() { // XHR to request a JS and a CSS var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://domain.tld/preload.js'); xhr.send(''); xhr = new XMLHttpRequest(); xhr.open('GET', 'http://domain.tld/preload.css'); xhr.send(''); // preload image new Image().src = "http://domain.tld/preload.png"; }, 1000); };
上面代码预加载了“preload.js”、“preload.css”和“preload.png”。1000毫秒的超时是为了防止脚本挂起,而致使正常页面出现功能问题。
与之相比, 若是用js的话, 要实现以上加载过程则会应用到页面上. 实现以下
window.onload = function() { setTimeout(function() { // reference to <head> var head = document.getElementsByTagName('head')[0]; // a new CSS var css = document.createElement('link'); css.type = "text/css"; css.rel = "stylesheet"; css.href = "http://domain.tld/preload.css"; // a new JS var js = document.createElement("script"); js.type = "text/javascript"; js.src = "http://domain.tld/preload.js"; // preload JS and CSS head.appendChild(css); head.appendChild(js); // preload image new Image().src = "http://domain.tld/preload.png"; }, 1000); };
这里,咱们经过DOM建立三个元素来实现三个文件的预加载。正如上面提到的那样,使用Ajax,加载文件不会应用到加载页面上。从这点上看,Ajax方法优越于JavaScript。