1 /** 2 * @fileOverview getScript support for css and js callback after load 3 * @author yiminghe@gmail.com,lifesinger@gmail.com 4 */ 5 (function (S) { 6 if (typeof require !== 'undefined') { 7 return; 8 } 9 var MILLISECONDS_OF_SECOND = 1000, 10 doc = S.Env.host.document, 11 utils = S.Loader.Utils, 12 jsCallbacks = {}, 13 cssCallbacks = {}; 14 15 S.mix(S, { 16 17 /** 18 * load a css file from server using http get, 19 * after css file load ,execute success callback. 20 * note: no support for timeout and error 21 * @param url css file url 22 * @param success callback 23 * @param charset 24 * @private 25 */ 26 getStyle:function (url, success, charset) { 27 28 var config = success; 29 30 if (S.isPlainObject(config)) { 31 success = config.success; 32 charset = config.charset; 33 } 34 var src = utils.absoluteFilePath(url), 35 callbacks = cssCallbacks[src] = cssCallbacks[src] || []; 36 37 callbacks.push(success); 38 39 if (callbacks.length > 1) { 40 // S.log(" queue css : " + callbacks.length); 41 return callbacks.node; 42 } 43 44 var head = utils.docHead(), 45 node = doc.createElement('link'); 46 47 callbacks.node = node; 48 49 node.href = url; 50 node.rel = 'stylesheet'; 51 52 if (charset) { 53 node.charset = charset; 54 } 55 utils.styleOnLoad(node, function () { 56 var callbacks = cssCallbacks[src]; 57 S.each(callbacks, function (callback) { 58 if (callback) { 59 callback.call(node); 60 } 61 }); 62 delete cssCallbacks[src]; 63 }); 64 // css order matters! 65 head.appendChild(node); 66 return node; 67 68 }, 69 /** 70 * Load a JavaScript/Css file from the server using a GET HTTP request, 71 * then execute it. 72 * @example 73 * <code> 74 * getScript(url, success, charset); 75 * or 76 * getScript(url, { 77 * charset: string 78 * success: fn, 79 * error: fn, 80 * timeout: number 81 * }); 82 * </code> 83 * @param {String} url resource's url 84 * @param {Function|Object} [success] success callback or config 85 * @param {Function} [success.success] success callback 86 * @param {Function} [success.error] error callback 87 * @param {Number} [success.timeout] timeout (s) 88 * @param {String} [success.charset] charset of current resource 89 * @param {String} [charset] charset of current resource 90 * @returns {HTMLElement} script/style node 91 * @memberOf KISSY 92 */ 93 getScript:function (url, success, charset) { 94 if (utils.isCss(url)) { 95 return S.getStyle(url, success, charset); 96 } 97 98 var config = success, 99 error, 100 timeout, 101 timer; 102 103 if (S.isPlainObject(config)) { 104 success = config.success; 105 error = config.error; 106 timeout = config.timeout; 107 charset = config.charset; 108 } 109 110 var src = utils.absoluteFilePath(url), 111 callbacks = jsCallbacks[src] = jsCallbacks[src] || []; 112 113 callbacks.push([success, error]); 114 115 if (callbacks.length > 1) { 116 // S.log(" queue js : " + callbacks.length + " : for :" + url + " by " + (config.source || "")); 117 return callbacks.node; 118 } else { 119 // S.log("init getScript : by " + config.source); 120 } 121 122 var head = utils.docHead(), 123 node = doc.createElement('script'), 124 clearTimer = function () { 125 if (timer) { 126 timer.cancel(); 127 timer = undefined; 128 } 129 }; 130 131 node.src = url; 132 node.async = true; 133 134 callbacks.node = node; 135 136 if (charset) { 137 node.charset = charset; 138 } 139 140 var end = function (error) { 141 var index = error ? 1 : 0; 142 clearTimer(); 143 var callbacks = jsCallbacks[src]; 144 S.each(callbacks, function (callback) { 145 if (callback[index]) { 146 callback[index].call(node); 147 } 148 }); 149 delete jsCallbacks[src]; 150 } 151 152 //标准浏览器 153 if (node.addEventListener) { 154 node.addEventListener('load', function () { 155 end(0); 156 }, false); 157 node.addEventListener("error", function () { 158 end(1); 159 }, false); 160 } else { 161 node.onreadystatechange = function () { 162 var self = this, 163 rs = self.readyState; 164 if (/loaded|complete/i.test(rs)) { 165 self.onreadystatechange = null; 166 end(0); 167 } 168 }; 169 } 170 171 if (timeout) { 172 timer = S.later(function () { 173 end(1); 174 }, timeout * MILLISECONDS_OF_SECOND); 175 } 176 head.insertBefore(node, head.firstChild); 177 return node; 178 } 179 }); 180 181 })(KISSY); 182 /** 183 * yiminghe@gmail.com refactor@2012-03-29 184 * - 考虑连续重复请求单个 script 的情况,内部排队 185 * 186 * yiminghe@gmail.com 2012-03-13 187 * - getScript 188 * - 404 in ie<9 trigger success , others trigger error 189 * - syntax error in all trigger success 190 **/