js 写插件入门(图片懒加载)
图片懒加载的插件有很多,其原理基本就是将图片链接先隐藏于data属性中,等滚动到特点位置后再将图片链接替换到 img src中
在不添加任何优化和修饰的情况下,核心代码逻辑非常简单,只做两件事即可
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
<meta name="referrer" content="no-referrer">
<title>图片懒加载demo | PHPer | Web前端 | 编程爱好者 | 郑凯文的个人网站</title>
<style>
img {
max-width: 100%;
}
</style>
</head>
<body style="padding: 20px;margin: 0;">
<div style="width: 640px;word-wrap: break-word;margin: 0 auto;">
<p><img src="img/loading-yellow.gif" data-original="https://pic4.zhimg.com/v2-098ae36dfa6d61ae3918092eefa699d1_r.jpg?source=1940ef5c"/></p>
<p><img src="img/loading-yellow.gif" data-original="https://pic4.zhimg.com/v2-098ae36dfa6d61ae3918092eefa699d1_r.jpg?source=1940ef5c"/></p>
<p><img src="img/loading-yellow.gif" data-original="https://pic4.zhimg.com/v2-098ae36dfa6d61ae3918092eefa699d1_r.jpg?source=1940ef5c"/></p>
<p><img src="img/loading-yellow.gif" data-original="https://pic4.zhimg.com/v2-098ae36dfa6d61ae3918092eefa699d1_r.jpg?source=1940ef5c"/></p>
<p><img src="img/loading-yellow.gif" data-original="https://pic4.zhimg.com/v2-098ae36dfa6d61ae3918092eefa699d1_r.jpg?source=1940ef5c"/></p>
<p><img src="img/loading-yellow.gif" data-original="https://pic4.zhimg.com/v2-098ae36dfa6d61ae3918092eefa699d1_r.jpg?source=1940ef5c"/></p>
<p><img src="img/loading-yellow.gif" data-original="https://pic4.zhimg.com/v2-098ae36dfa6d61ae3918092eefa699d1_r.jpg?source=1940ef5c"/></p>
<p><img src="img/loading-yellow.gif" data-original="https://pic4.zhimg.com/v2-098ae36dfa6d61ae3918092eefa699d1_r.jpg?source=1940ef5c"/></p>
<p><img src="img/loading-yellow.gif" data-original="https://pic4.zhimg.com/v2-098ae36dfa6d61ae3918092eefa699d1_r.jpg?source=1940ef5c"/></p>
<p><img src="img/loading-yellow.gif" data-original="https://pic4.zhimg.com/v2-098ae36dfa6d61ae3918092eefa699d1_r.jpg?source=1940ef5c"/></p>
<p><img src="img/loading-yellow.gif" data-original="https://pic4.zhimg.com/v2-098ae36dfa6d61ae3918092eefa699d1_r.jpg?source=1940ef5c"/></p>
</div>
</body>
</html>
其实核心JS:
就这些就可以实现图片懒加载了
/*
* 监听函数
* obj 监听对象
* type 监听事件
* handle 执行函数
*/
function addEvent(obj,type,handle){
try{
obj.addEventListener(type,handle,false);
}catch(e){
try{
obj.attachEvent('on'+type,handle);
}
catch(e){
obj['on' + type]=handle;//早期浏览器
}
}
}
var render = function() {
// 所有需要懒加载的元素
var nodes = document.querySelectorAll('[data-original]');
// 打印所有图片,可以看到各元素对象有一些属性,可以自己调试看一下
console.log(nodes)
// 获取滚动距离
var scrollHeight = window.pageYOffset + document.documentElement.clientHeight
// 遍历需要懒加载的元素
for (var key in nodes) {
if (nodes.hasOwnProperty(key)) {
var item = nodes[key]
// 滚动到图片位置时,替换src
// 这里的item.offsetTop就是图片元素距离顶部的距离
if(scrollHeight >= item.offsetTop) {
// 从data属性中获取original图片链接
item.setAttribute('src', item.dataset.original)
}
}
}
}
// 监听两个事件,第一,当页面滚动到某个图片元素位置时,加载图片
addEvent(document ,'scroll', render)
// 当页面及资源完全加载后
addEvent(window ,'load', render)
到这里就可以完成“图片懒加载”的功能了。
那在实际使用情况下,每次滚动都会遍历并执行懒加载的操作,显然这样是很不合理的,下面进行一些优化
待优化的点:
1.已经加载好的图片,不再重新再被document.querySelectorAll('[data-original]')查询到,也就是后面不再重新设置src
我的一开始的思路是,直接把 data-original 删除即可,用removeAttribute,即:item.removeAttribute('data-original')
2.第一步做完发现,由于监听了滚动事件,每次滚动,函数可能被执行n多次,可以再优化一下,加入函数节流
3.如果待加载的图片地址404了,即“图裂了”,我想优化一下,换成一张好看点的404占位图
优化思路是:判断图片链接响应状态,如果不是200,则填充本地404图片地址
4.现在的代码是在刚滚动到图片位置时,就把src改了,比如我们作为开发人员,我可以通过控制台调试,查看实际代码是否工作,但是作为老板,他刚进来看到就是已经替换好的图片,老板都没都根本看不清是不是懒加载,他估计会想:“这程序员到底有没有做这个功能”,遇到这种情况怎么办呢?我们需要在滚动到图片位置的条件上加点偏移量,即需要让老板看到滚动到图片时,图片还是Loading的情况,让他看清情况后,我再把图片地址改成真实图片,甚至可以加点延时和渐显的效果。
5.将某些设置做成可配置项
一步步来,我先完善下代码,把代码插件化,然后把优化点1完成:
优化功能点1
;(function(undefined) {
"use strict"
var _global
// 合并对象(深拷贝)
function extend(defaults, n) {
var n = n || {};
for (var x in defaults) {
// 对于使用时,没有设置的参数;用默认参数代替
if (typeof n[x] === 'undefined') {
n[x] = defaults[x];
}
}
return n
}
/*
* 监听函数
* obj 监听对象
* type 监听事件
* handle 执行函数
*/
function addEvent(obj,type,handle){
try{
obj.addEventListener(type,handle,false);
}catch(e){
try{
obj.attachEvent('on'+type,handle);
}
catch(e){
obj['on' + type]=handle;//早期浏览器
}
}
}
// 插件函数
function Klayz(opt){
// 未使用new关键词时
if (!(this instanceof Klayz)){
// 等于再new一个
return new Klayz(opt)
}
this._init(opt)
}
Klayz.prototype = {
constructor: this,
_init: function (opt) {
// 监听两个事件,第一,当页面滚动到某个图片元素位置时,加载图片
addEvent(document ,'scroll', this._render.bind(this))
// 当页面及资源完全加载后
addEvent(window ,'load', this._render.bind(this))
},
_render: function () {
var nodes = document.querySelectorAll('[data-original]')
console.log(nodes)
var scrollHeight = window.pageYOffset + document.documentElement.clientHeight
console.log(scrollHeight)
for (var key in nodes) {
if (nodes.hasOwnProperty(key)) {
var item = nodes[key]
if(scrollHeight >= item.offsetTop) {
// 设置真实图片链接
item.setAttribute('src', item.dataset.original)
// 移除data-original后,下次不再遍历该原素
item.removeAttribute('data-original')
}
}
}
}
}
// 最后将插件对象暴露给全局对象
_global = (function(){ return this || (0, eval)('this'); }());
if (typeof module !== "undefined" && module.exports) {
module.exports = Klayz;
} else if (typeof define === "function" && define.amd) {
define(function(){return Klayz;});
} else {
!('Klayz' in _global) && (_global.Klayz = Klayz);
}
}());
优化功能点2
/** 节流
* 应用场景:用户进行高频事件触发(滚动),但在限制在n秒内只会执行一次。
* 实现原理: 每次触发时间的时候,判断当前是否存在等待执行的延时函数
* @params fun 传入的防抖函数(callback) delay 等待时间
* */
function throttle(fun, delay){
delay = delay || 1000
let flag = true
var f = fun
return function (...args) {
if (!flag) return;
flag = false
setTimeout(function () {
f.apply(this, args)
flag = true
}, delay)
}
}
优化功能点3
// 验证图片是否404状态
function validateImage(url)
{
var xmlHttp
if (window.ActiveXObject)
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest)
{
xmlHttp = new XMLHttpRequest();
}
xmlHttp.open('Get', url, false);
xmlHttp.send();
if(xmlHttp.status==404){
return false;
}else{
return true;
}
}
优化功能点4
主要是淡入的效果
// 设置元素透明度,透明度值按IE规则计,即0~100
function SetOpacity(el, v){
el.filters ? el.style.filter = 'alpha(opacity=' + v + ')' : el.style.opacity = v / 100;
}
/*
* 淡入效果(含淡入到指定透明度)
* el 需要淡入的元素
* speed 淡入速度,正整数(可选)
* opacity 淡入到指定的透明度,0~100(可选)
*/
function fadeIn(el, speed, opacity){
speed = speed || 20;
opacity = opacity || 100;
//显示元素,并将元素值为0透明度(不可见)
el.style.display = 'block';
SetOpacity(el, 0);
//初始化透明度变化值为0
var val = 0;
//循环将透明值以5递增,即淡入效果
var timer = setInterval(function() {
if (val <= opacity) {
SetOpacity(el, val)
val += 5
} else {
clearInterval(timer)
}
}, speed);
}
优化功能点5(最终版)
也就是最终的完成版,至少是v1可进行测试的版本了
;(function(undefined) {
"use strict"
var _global
// 合并对象(深拷贝)
function extend(defaults, n) {
var n = n || {};
for (var x in defaults) {
// 对于使用时,没有设置的参数;用默认参数代替
if (typeof n[x] === 'undefined') {
n[x] = defaults[x];
}
}
return n
}
/*
* 监听函数
* obj 监听对象
* type 监听事件
* handle 执行函数
*/
function addEvent(obj,type,handle){
try{
obj.addEventListener(type,handle,false);
}catch(e){
try{
obj.attachEvent('on'+type,handle);
}
catch(e){
obj['on' + type]=handle;//早期浏览器
}
}
}
// 验证图片是否404状态
function validateImage(url)
{
var xmlHttp
if (window.ActiveXObject)
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest)
{
xmlHttp = new XMLHttpRequest();
}
xmlHttp.open('Get', url, false);
xmlHttp.send();
if(xmlHttp.status==404){
return false;
}else{
return true;
}
}
// 设置元素透明度,透明度值按IE规则计,即0~100
function SetOpacity(el, v){
el.filters ? el.style.filter = 'alpha(opacity=' + v + ')' : el.style.opacity = v / 100;
}
/*
* 淡入效果(含淡入到指定透明度)
* el 需要淡入的元素
* speed 淡入速度,正整数(可选)
* opacity 淡入到指定的透明度,0~100(可选)
*/
function fadeIn(el, speed, opacity){
speed = speed || 20;
opacity = opacity || 100;
//显示元素,并将元素值为0透明度(不可见)
el.style.display = 'block';
SetOpacity(el, 0);
//初始化透明度变化值为0
var val = 0;
//循环将透明值以5递增,即淡入效果
var timer = setInterval(function() {
if (val <= opacity) {
SetOpacity(el, val)
val += 5
} else {
clearInterval(timer)
}
}, speed);
}
/** 节流
* 应用场景:用户进行高频事件触发(滚动),但在限制在n秒内只会执行一次。
* 实现原理: 每次触发时间的时候,判断当前是否存在等待执行的延时函数
* @params fun 传入的防抖函数(callback) delay 等待时间
* */
function throttle(fn, delay){
delay = delay || 1000
var flag = true
var f = fn
return function () {
if (!flag) return;
flag = false
setTimeout(function () {
f.apply(this)
flag = true
}, delay)
}
}
// 插件函数
function Klayz(opt){
// 未使用new关键词时
if (!(this instanceof Klayz)){
// 等于再new一个
return new Klayz(opt)
}
this._init(opt)
}
Klayz.prototype = {
constructor: this,
_init: function (opt) {
var defaults = {
defaultImg: 'data:image/gif;base64,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', // 默认的占位图
errorImg: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAVZklEQVR4Xu2dfbQcdXnHn2d2kwABDxhArELF0mJBEVFoC7QBLS8qkOxsck3uzuaSnb1EwqseBbVUAhwsLx6gQSLJ3dnr3p1N7OXubJAXRVAoUNoCGmnB4uFAW7EHU7S+IUru3Xl6Ji+cJHdf5u2385uZZ8/hD879/b6/5/k8883OzvxeEPjDBJhAVwLIbJgAE+hOgA3CVwcT6EGADcKXBxNgg/A1wAT8EeBvEH/cuFdKCLBBUlJoTtMfATaIP27cKyUE2CApKTSn6Y8AG8QfN+6VEgJskJQUmtP0R4AN4o8b90oJATZISgrNafojwAbxx417pYQAGyQlheY0/RFgg/jjxr1SQoANkpJCc5r+CLBB/HHjXikhwAZJSaE5TX8E2CD+uHGvlBBgg6Sk0JymPwJsEH/cuFdKCLBBUlJoTtMfATaIP27cKyUE2CApKTSn6Y8AG8QfN+6VEgJskJQUmtP0R4AN4o8b90oJATZISgrNafojwAbxx417pYQAGyQlheY0/RFgg/jjxr1SQoANkpJCc5r+CLBB/HHjXikhwAZJSaE5TX8E2CD+uHGvlBBgg6Sk0JymPwKeDWI0Wlf7G4p7MYHoCeiF3DVeovBnEKI1XgbhtkxACgKIa9ggUlSCg5CSABtEyrJwULIQYIPIUgmOQ0oCbBApy8JByUKADSJLJTgOKQlEbRAEeERKMBxUqggQwGkdE5bBICVNPT1V1eBkpSJQNa2H2SBSlYSDkYkAG0SmanAs0hFgg0hXEg5IJgJsEJmqwbFIR4ANIl1JOCCZCLBBZKoGxyIdATaIdCXhgGQiwAaRqRoci3QE2CDSlYQDkolAqgyywWyeqEDmRAD7JCA4CRHeDgCPE9ATQLiFMpkto8OLtspUII4lWgKpMEjFbJ6CANcBYN9pKwR0U1nLXxltWXh0WQgk3iBGo/kFILzeI/AfUdteXh5ZssVjP26eMAKJNYgxMfUhUJSngtTLJrpmtJjn9fJBIMa8b3INYlq/AIADg9ZnZgaPWnV+7sWgOtw/ngQSaZCqad1JAKtCKQnRFr2YPyEULRaJHYHEGcRoNE8Hwu+GWgkfC2NCHZ/FIiOQPIOY1t0AcF7YRG2CM0eL6oNh67Ke3AQSZZDJycnMb7ZlnfcYC8LGjgiXlQrq2rB1WU9uAokySBhPrrqVi4jWl4v5T8pdTo4ubALJMohpjQLAhrAh7dR7VNfUhYK0WVZSAskySMOqAcEKIawRXtUL6qFCtFlUWgJsELelYYO4JZWodskyCN9iJerilCGZZBkkhOkl/CNdhstSnhgSZRB+zCvPhZWUSBJlEKcoVdPaTACLwi4QvygMm2g89BJnkB1rP/DxMPEj4JUlLXdTmJpx1zLq1vudHPSi+kzcc+kVf+IM4iRbMVs3ItAVYRQOEe8pFXKhT10JI7aoNMbM5p8jYQ0VAIVoZKWW/5eoYhE9biIN4kAzTOt5ADg6KMAD5s7sNzQ09LugOknpv3MyaA0ADt+Z08uAmRG9sOjhpOS4ex6JNcgOkzS/BYBn+Szc64R4ermQe9Jn/8R1G5uY+hgqSg0BDt4ruZ8pqIysLCy+P2lJJ9og23+0NzafRWSvB4A/dF08gq/rRXW56/YpaGjUp/KAWAPA+Z3Txd/aYJ8/quWnkoQj8QZxinXH5OT++05nr7WJ8gh4RJcCzgDgk4R0e7mgfj1JRQ6ai9GwCmTTBKLzq6PnhwhppFzI14OOKUv/VBhkd9iVCeu9ShZOJBtOQoC3A8Ljbbv9tD2PtqwaGvqVLIWRJY5qvVkmxDEv8SDRqlIxL2rSqJdQArdNnUECE0uRgGG2LgEgX2tgiPDycjH393HHxQaJewUFxV81W1cQ0I0B5T+va+oNATUi7c4GiRS/nIMbjdbVQBTKdkcIcG1JU6+WM9P+UbFB+jNKVYtq3bqBEMLeWfJmXVNDeXE76GKwQQZNXOLxDNNyfjNcKijEO3RNvViQtjBZNogwtPESNkzLeerkLFkW9iGAallTdWEDCBBmgwiAGifJNWvWKO886jjn7bg2oLg36Zo6PKCxAg/DBgmMML4CN09MzH8rzq8BYn6gWRBtPmBe+xNDQ0PbBjquj8HYID6gJaFLrWYtmMmAM+nw49Hkgw8o07Bs5crcL6MZ392obBB3nBLVasxsvjODWCOCD0ec2KMzRMtWFfOvRBxH1+HZILJWRlBc442pP7ZBcbZH+gtBQ3iSRYCnAGlZqZB/yVPHATVmgwwItAzDjG2cOi5jKzUCOF6GeHaL4dmMYi87f3jJc5LF5SzhfpgATusYl49NzdFrgr3e2iLAIyVN7Xtsmtcx09i+OrH5z0ixnd8cgReRCeL3EmQyn9CXL3pakL4vWTaIL2zx6jRWb52GaNd6TPWXIiECeMW53SoX8o9KEdCOTUD4G0SWYoiIwzBbHwWynUe5h4jQF6D5S0R7Wamw5AEB2p4l2SCekcWnw1jDUpHI+ebYPz5RAwDBG5TBZeXh3Oao42aDRF0BQeMbdasACn4NiLKChhAui4TDpWJuk/CBegzABomSvqCxK/VmGT2uAhQUSnBZm8r6irwRXMifAhvEHzdpe1UbrYuJ6HZpA/QRGBFeUi7mvuKja+AubJDACOURMOrWZwEhmTtAElyhF9WbB02bDTJo4oLGq5rWFwngGkHyUsgiwNUlTb12kMGwQQZJW9BYhmn9HQB8TpC8bLI36Jr6+UEFxQYZFGlB41Qb1m1EcJkgeVll1+qaOpCc2SCyXgIu4jLqzfWAeIGLpklsMqZrqvDc2SBdLp2qaZ0DQPNLWv4fpLu6iNBwDiwFLEoX2wADIgCzrKlCGbBBOhR0Q/2ukzOYeQgA9gUETS+ojQHWvedQ69ffs192/jbHHEtkiSmiOF5AhG8Stb+la0u/KSoGNsheZI363UcDzHwHEN/x5p+QVuqF/NdEFcGt7ldq1oJ9M+DEcY7bPglrNxBT7M6MDbIbjerk5CE0nX0ICI7b+8JCotFSMV+J6oJzVgEqgI45PhJVDFGNiwD/QwS36EX1lkHHYJitcQA6v+O4aVoP4hwA+tq27ENdF8fsIHShrql3DrpIlfrdRyHOOLdVJw96bAnGW0tIt5QL+f+OKhbnuDlC+BQCjOwRQ5oMUjWtJgGo/YtAl+pafmBTOcbNze+ziWqA9IH+sSWnBQLcbe8whjRrQ8Y3WmfbNlwFAKdsJ50Wg1Qa1hgSlN1eXojw6VJBvdVte7/tKo3WSc50dQB4j1+NWPYj+hu9mP9SkNhrk/e8Y2Zm+khow7sR4V1twJcUhV604fcvjQ4Pb/WrvXbt/fP2X/D7m4jg0lQYpGI2b0RA7/vGKnCFPixublB1o7WQ7O3b8rg/Gctv1aXqh2fpWu7bXkIan5w8zH4j+xFEWEwA7wOAIwFgbg+N1wDgRSD6V+eQ1um5M495PRumMmEtwwwerRdynqb3xGpNeuAt/kP4l65TESt162zE7eY41MuFEue2RPAizJs5qTw09H9u8hhrtD6oEJ0BAM6eBWe66dOrjWMUsukxBPpOqZj/vhu99bXJI1aNDP3YTdtdbWJjED8nJ3UCEfYEOsNs5oCwBggHeAEf57YI8L2Spn7ITQ7jG6feY9uZ1UD2RdD/SDg3knu3aQPQuplpWrdq5RLnpORQP7EwiLMUVSFohpY54nV6IffFoHoVszmMOx7lzgmqFZf+CPBcSVPf2y9e51/rOUp2NSGsBhD/jwcC/pqA1mFGWVdavvjlfvG5/bv0Bhmr33Wagsq93U9rdZvqrHaBZpkaE00dFIzsPYvvrAN0JIDnyi7MYZjWJwHAOYTnsADD+e36UyJaUy7mnZOSA3+kNshYbeo4JavcCwSHB860gwASfLlUVD/rVdswrYsAIJIVc15jDau9Yw6ys+eOrjjvP3tpVhvN24lQgnNF8HZdywU+O0Vag2x/7Ldt+j4AeH9YRe6sg7fpWu5TbseoNqzPEMHAV8q5jU9EO+f2ZQZh4QWF3A966Rum9d2dP8JFhOFDkx7WtXyg/YylNMjk5OS+v96WvR+7bSHpA1WfLq5OUzLqzb8FxIGukAs/Ve+KhPC5ckHtekAoEWHVtLaGsZcXAtxFRD9ExGMIYKn3aGf1+F9dU9/mV0dKg1RMq4mu3pL7TXt2PwRYX9JU596546dqNr9EgANbGRdeZoGVHtY1tee/wlXTepYAjg0yEgH9WMGMXiosdmZlb/+M1a0zFARnh5Sgt9j/rmvqrPl6buKVziDVhjVGHt6Su0nSbZtuR44ZZvNWALzcrU6S2iHSGaVC/s2Ldu/cKo3WVUh0XdCcnZeGpYJ69yz9emsxIrWC6oPPd2BSGaRqtm4kIO9vyQPT202AYEIvqm9OcquY1p0IsCrMIeKihQhfLhW6P8Qw6lNDgEooC9SUaTyo0+E86xqNg+bRvq5eRvbjikBLS1p+ql+73f8ujUEM03I2MXA2M4j8g4AbS1quYNQt5wXgisgDiiaAn9tAx49q+Z90Gn7nvLN/BIB9wghP19SO1+L23zeNlh3GGADwOmQyC73sSC+FQar15gWEGMpz65BAOlM/JwFoKDy9eCkhwq2lgvrpblEbpuXcdoW21mVABgFEeLBUUF1PdYncIFWzuYQA74rX5ZP8aKltn1AeWbKlU6aG2bwcAEOdHT0ogzj5IMJlpYK61k0VIzVIdaP1YbLB2RE8NfOY3BQl6ja9NlfYsRis/VjYb8kHaRDnXBMF555aKpzT9xi5yAwy3mgdbxM55kjZ9PCoL//+4ysKnLlyWH2wU0tRTxkHaZCdebnahigyg/Q6yq1/CbmFMAKIW/RC7oTOt1atjwLQ/SLGjsAgzuTis0uFxT0P/mGDiKh2rDXpNl3Ld5x6U21YNxPBZ0SkF4VBAOBmXVN7vlZgg4iodow1bYTFox1e2DkpGfXm9wFRyFr7KAyCgN8rabme61rYIDG+mEWEPjN35sBOy1kr9cmjELMviBjT0YzCIDueaNEf9TrznQ0iquLx1H1U19SFnX+cty4konWi0orKIP22hmKDiKp4HHWJ1ujFfMdNDYx6swWIi0WlFaFBWrqmdt0+ig0iquIx1EXE1aVC7qsdn2A1rB8BwZ+ISitCgzyja+rx3fJig4iqeAx1e03mM0xrm8i19xEa5BVdU/+ADRLDC3bQIaMNp5VWqM4ExD0+O/cZDm0jhE55RWiQtq6pXY/e5m+QQV+FEo83JwvHrFim/sfeIVYazb9CwlnGCTOVCA0C2TYcPDKi/rxTPmyQMKscc60ZZc4hq4bP/dksg5jWCML2YxyEfaI0CMLMsSVt6IdsEGHlTYQw6ZqqdPyBXm+uAURnGx9hnygNYlP79NHi0kdCMchYvblG6QILAR4paaqztWTfD8/F6oto4A26reqrNFpFJJoQGVCkBrHhmNEVs28tnXw932KxQUReJtFq23b23Z32varWN59MaP+TyOiiNMg+OPethcI5vwjlG6TXv/z8DSLyEhKvjUQf7LQR9Pj45GH2nOwrIiOI0CDbdE2d1y03z98gbBCRl0nE2kSL9GL+Gx1/h5it15xThEVFGKFBXtY19Qg2iKjKJkgXEW4sFVRn84xZH6NhPdPpLMiw0o/MIERP68X8iWyQsCqZZB2Ex/WC+pedv0GsDQAwKip9G+jwTjuoVDdtPpzatqczPTzFSLRBL+a7busU2S1Wrx/7nhLkxmES6Pqod3zj5nNt2+54+xVGAAR0ZVnL37S3VqVuXYkIN4QxRpcf4eeWNPVe6b5BRCXMumIIjI+3DrTnUMcnPWGNuG0aj7xwZe6/dumNb2q9y25Tz93kg4yNiDQ9Z/qgXse5ef4GCesxb5DEuG80BKqmdQ8BnCNydOe0XCL6wc6Vi+cJHYvonlIx33MMNojICiRMO/AZkbLxILhCL/Y+2JUNIlvRJI6nWm+eQIBPAELX9wYSh79HaAjwO7ttn9Jtc7xdjT0bJKz3IHEByXHuScBoWNcDwRfizoUAri9r6lX98mCD9CPEf9+DQK1mLZhW4AlEIasLn0eEDW0bt2QU+gDR9l31jxZQguf3wbknd5tesvt4bBAB9JMuWW20LiCiUDcbJ4IH59iwfPd1Ges3bjw4a8/bBIB/HTLTC3RNHXOjyQZxQ4nbzCJgmK0HAMj1Lun9EBLQqWUtP2tCpFGzToUMOHsBh/TBB3Qtd7ZbMTaIW1Lcbg8CFbN5CgI8ENrx3G9k3qLri36zN+a1pvmW+bDfr8LAT0CvoYJn6sPqP7vV82wQfg/iFm3y21Ub4e2VhaAcW9IWz1rVt2Hj1LEZW3k2JJoX6pp6pxet0A3iZXBuKz8BG+iqTrc+uyI3zOZaALwkhEw67rZeaVhjGMqZld6O+96VT6gGCQESS8hGgODf5tBrJ69YseK33UIz6ta9gPDxEELfREB3OIbcfgtHeDEgLAtB9xu6pi7yo+PZILxU1g/mePchoq+Wi/nVvbKo1JvrEPFCCTO9Q9fUi/3GxQbxSy59/frev4+ZLU0BqkuDhkDTi2ojSDxskCD00tV3mohy5WL+vl5pVxtTZ9mkmAhwcGR4iF4FVDRdy307aAxskKAE09Qf4VW7DQu77QCyC4UzZ8sG5TpE+tig8RDR/ZDNXlVevqjjAaRe42GDeCXG7V84YO7Mnw4NDbX7oRhvWEttGy4ChI5HKvTr7+XvzoYhNsK6ckEN9cRkzwZx3oN4CVzWtoqikG3bb+bv9f9lzWtQcY0W866vA6PRPB8JVxNA17XfAeJ+EgHWlTS1FkCja1fPBhERBGumg0ClPrUYERcBOP/BQQGy/gkR3acg3ttruWwA/Te7skHCoMgangk4t18EsJR2nDly6M7/Mh2EnGMXtgLRVlSUpxCp1e2Ias9BuOjABnEBiZsMhkDNsha0X595W5vw0Gxmn5/OJdzqZkq6yOjYICLpsnbsCbBBYl9CTkAkATaISLqsHXsCbJDYl5ATEEmADSKSLmvHngAbJPYl5AREEmCDiKTL2rEnwAaJfQk5AZEE2CAi6bJ27AmwQWJfQk5AJAE2iEi6rB17AmyQ2JeQExBJgA0iki5rx54AGyT2JeQERBJgg4iky9qxJ8AGiX0JOQGRBNggIumyduwJsEFiX0JOQCQBNohIuqwdewJskNiXkBMQSYANIpIua8eeABsk9iXkBEQSYIOIpMvasSfABol9CTkBkQTYICLpsnbsCbBBYl9CTkAkATaISLqsHXsCbJDYl5ATEEmADSKSLmvHngAbJPYl5AREEmCDiKTL2rEnwAaJfQk5AZEE2CAi6bJ27AmwQWJfQk5AJIH/B8VMTm4mVSJpAAAAAElFTkSuQmCC', // 图裂的占位图
offset: 0, // 向上的偏移量,单位px
}
// 没有设置的参数,使用默认值
this.opt = extend(defaults, opt) // 得到的this.opt, 在方法中调用;
// 监听两个事件,第一,当页面滚动到某个图片元素位置时,加载图片
addEvent(document ,'scroll', throttle(this._render.bind(this)))
// 当页面及资源完全加载后
addEvent(window ,'load', throttle(this._render.bind(this)))
},
_render: function () {
var nodes = document.querySelectorAll('[data-original]')
console.log(nodes)
var scrollHeight = window.pageYOffset + document.documentElement.clientHeight
console.log(scrollHeight)
for (var key in nodes) {
if (nodes.hasOwnProperty(key)) {
var item = nodes[key]
// 如果src是空的,未设置的,则填充默认占位图
if(!item.getAttribute('src')) {
item.setAttribute('src', this.opt.defaultImg)
}
// 计算时加入偏移量
if((scrollHeight - this.opt.offset) >= item.offsetTop) {
// 设置真实图片链接
var imgUrl = item.dataset.original
// 图片响应状态
var imgStatus = validateImage(imgUrl)
if(imgStatus) {
// 正常情况
item.setAttribute('src', item.dataset.original)
} else {
// 404图片设置404占位
item.setAttribute('src', this.opt.errorImg)
}
// 移除data-original后,下次不再遍历该原素
item.removeAttribute('data-original')
// 图片淡入
fadeIn(item)
}
}
}
}
}
// 最后将插件对象暴露给全局对象
_global = (function(){ return this || (0, eval)('this'); }());
if (typeof module !== "undefined" && module.exports) {
module.exports = Klayz;
} else if (typeof define === "function" && define.amd) {
define(function(){return Klayz;});
} else {
!('Klayz' in _global) && (_global.Klayz = Klayz);
}
}());
上面代码看着很多,其中有很长一段图片的base64代码,因为不想额外引用固定的图片地址,所以就转成base64引用了,如果去掉base64的图片内容,代码就清晰很多了
调用插件:
Klayz({
defaultImg: './img/loading-yellow.gif',
errorImg: './img/404.png',
offset: 100
})
demo:http://returnc.com/demo/layz.html
又重复造了个轮子。。。