javascript,css延迟加载器
/** * js/css LazyLoad * * 变量hash记录已经加载过的资源,避免重复加载 * * Z.loadScript('a.js', function() { ... }) * * Z.loadScript('a.js', option, function() { ... }) * * 加载多个js后才回调,如果某个js文件没有下载下来则会报错,且不会执行回调函数 * Z.loadScript(['a.js','b.js','c.js'], function() { ... }) * * option * charset: 'utf-8' * scope: xx * * 加载多个css后才回调,IE6/7/8/9和Opera中支持link的onreadystatechange事件 * Firefox/Safari/Chrome既不支持onreadystatechange,也不支持onload。使用setTimeout延迟加载 * * Z.loadLink('a.css', function() { ... }) * */ var Z = { error : function(msg) { throw new Error(msg) }, ua : window.navigator.userAgent.toLowerCase(), ie : /msie/.test(this.ua) && !/opera/.test(this.ua) }; (function(Z) { var doc = window.document; var hash = {}; var types = ['Array', 'Function', 'Object', 'String', 'Number', 'Boolean', 'Date']; var nativeForEach = types.forEach; var emptyFunc = function () {}; var head = doc.head || doc.getElementsByTagName('head')[0]; function forEach(obj, iterator, context) { if (obj == null) return; if (nativeForEach && obj.forEach === nativeForEach) { obj.forEach(iterator, context) } else if ( obj.length === +obj.length ) { for (var i = 0; i < obj.length; i++) { if (iterator.call(context||obj[i], obj[i], i, obj) === true) return } } else { for (var k in obj) { if (iterator.call(context||obj[k], obj[k], k, obj) === true) return } } } forEach(types, function(name) { Z['is' + name] = function(obj) { if (obj === undefined || obj === null) return false; return Object.prototype.toString.call(obj) === '[object ' + name + ']' } }); function createEl(type, attrs) { var el = doc.createElement(type), attr; for (attr in attrs) { el.setAttribute(attr, attrs[attr]) } return el } function done(list, obj) { hash[obj.url] = true; list.shift(); if (!list.length) { obj.callback.call(obj.scope) } } function load(type, urls, option, callback) { if (Z.isString(urls)) { urls = [urls] } if (Z.isFunction(option)) { callback = option; option = {} } option = option || {}; var obj = { scope: option.scope || window, callback: callback || emptyFunc }; var list = [].concat(urls); var charset = option.charset || 'utf-8'; forEach(urls, function(url, i) { var el = null; // 已经加载的不再加载 if (hash[url]) { Z.error('warning: ' + url + ' has loaded.') } if (type === 'js') { el = createEl('script', { src: url, async: 'async', charset: charset }) } else { el = createEl('link', { href: url, rel: 'stylesheet', type: 'text/css' }) } (function(url) { if (Z.ie) { el.onreadystatechange = function() { var readyState = this.readyState; if(readyState === 'loaded' || readyState === 'complete') { obj.url = url; this.onreadystatechange = null; done(list, obj) } } } else { if (type == 'js') { el.onload = function() { obj.url = url; done(list, obj) }; el.onerror = function () { Z.error(url + ' 不存在'); } } else { setTimeout(function() { obj.url = url; done(list, obj) }, 100) } } })(url); if (type === 'js') { head.insertBefore(el, head.firstChild) } else { head.appendChild(el) } }) } Z.loadScript = function(urls, option, callback) { load('js', urls, option, callback) }; Z.loadLink = function(urls, option, callback) { load('css', urls, option, callback) } })(Z);