项目开发中提出了一个新的需求。
因为版本更新带来的html、js等的更新,但客户浏览器或多或少都会存在缓存问题。
这就需要根据版本信息去动态加载外部js。
但html中内置的一些javascript代码需要调用动态加载js中的参数和方法。
就导致了加载外部js必须阻塞内置的一些javascript代码。
利用document.createElement方法去创建scrip节点,但不能阻塞内置的javascript代码。
在W3help里找到了解决方法。
这里只截取解决方法的代码,还有很多测试加载顺序的代码就不贴出来了。可以参考
function loadJS(url, success) { var domScript = document.createElement('script'); domScript.src = url; success = success || function(){}; domScript.onload = domScript.onreadystatechange = function() { if (!this.readyState || 'loaded' === this.readyState || 'complete' === this.readyState) { success(); this.onload = this.onreadystatechange = null; this.parentNode.removeChild(this); } } document.getElementsByTagName('head')[0].appendChild(domScript); } //执行加载外部 JS 文件,从a.js开始执行加载。 loadJS('a.js',function (){ loadJS('b.js',function (){ loadJS('c.js',function (){ alert('ok'); }); }); });
通过进一步了解onload和onreadystatechange,发现IE9/10同时支持script元素的onload和onreadystatechange事件。
所以上面的代码在IE9/10中会执行两次if中的代码。
替换方法就是写成
function loadJS(url, success) { var domScript = document.createElement('script'); domScript.src = url; success = success || function(){}; //domScript.onload = domScript.onreadystatechange = function() { if(navigator.userAgent.indexOf("MSIE")>0){ domScript.onreadystatechange = function(){ if('loaded' === this.readyState || 'complete' === this.readyState){ success(); this.onload = this.onreadystatechange = null; this.parentNode.removeChild(this); } } }else{ domScript.onload = function(){ success(); this.onload = this.onreadystatechange = null; this.parentNode.removeChild(this); } } document.getElementsByTagName('head')[0].appendChild(domScript); } //执行加载外部 JS 文件,从a.js开始执行加载。 loadJS('a.js',function (){ loadJS('b.js',function (){ loadJS('c.js',function (){ alert('ok'); }); }); });