• 慈善基金进社区 点对点帮扶居民 2019-04-10
  • 三面悬崖的3197哨所 战士背饮用水要走"天梯" 2019-04-10
  • 习近平《在深入推动长江经济带发展座谈会上的讲话》单行本出版 2019-04-09
  • 女子在自家院子乘凉 被后山滚落千斤巨石砸死 2019-04-07
  • 很深刻。当今城市化基本出于房地资本的繁衍需要与维持粗陋GDP的无奈,越来越显露其反动性。 2019-04-03
  • 故都之秋,惊艳了整个华东文章中国国家地理网 2019-04-03
  • 中国虚拟现实创新创业大赛南昌赛区颁奖仪式举行 2019-03-31
  • 邯郸“廉政诊所”筑起基层首道廉政防线 2019-03-31
  • 蔡英文,赖清德,李登辉,陈水扁..... 2019-03-24
  • 【北京海之沃车型报价】北京海之沃4S店车型价格 2019-03-22
  • 上海电影节第三日:电影市场热议产业新形势 2019-03-22
  • 特朗普雇佣资深律师应对涉俄调查 2019-03-18
  • 两部门:支持建设一批乡土经济活跃的农业产业强镇 2019-03-17
  • 法国总统马克龙首次访华 法国居民期待成果 2019-03-16
  • 黑龙江p62历史开奖结果

    黑龙江福彩p62开奖结果:完美异步加载javascript并回调函数

    稿件来源: 阳光企业网站管理系统   撰稿作者: 太阳光   发表日期: 2015-08-08   阅读次数: 131   查看权限: 游客查看

    加载js方法很,但判断是否成功方法却少有。

    黑龙江p62历史开奖结果 www.tgpe.net 异步加载js文件,大部分都是生成script标签插入文档,比如我们看看seajs3.0的源码:

        var supportOnload = "onload" in node
        if (supportOnload) {
          node.onload = onload
          node.onerror = function() {
            emit("error", { uri: url, node: node })
            onload(true)
          }
        }
        else {
          node.onreadystatechange = function() {
            if (/loaded|complete/.test(node.readyState)) {
              onload()
            }
          }
        }

    从源可以看出只要不支持onload事件的浏览器压根就没有判断onerrer事件,也就是说无法知道文件加载失败情况。

    其实主要是IE8及以下浏览器对js无onload事件支持,但支持onreadystatechange事件,而readyState主要有:

    0 "uninitialized" 未初始化
    1 "loading" 载入中
    2 "loaded" 载入完成已经接收到全部响应内容
    3 "interactive" 正在解析响应内容
    4 "completed" 响应内容解析完成

    而且特别是在IE下,往往因先赋值src再插入节点还是先插入节点再赋值src生成readyState返回loaded、completed不一至,所以需要两者一起判断。而且更可气的是不管文件是否成功加载仍会按顺序影响这些readyState,也就是说靠onreadystatechange事件无法分辨是否成功加载js文件了……

    突然发现一个点子,把js以vbscript文档加载进入文档,必然会引发window.onerror事件:

        var script = document.createElement("script");
        if ("onload" in script) {
            script.onload = function () {};
            script.onerror = function () {};
        } else {
            script.language = "vbscript";
            var _timeOut = setTimeout(function () {
                alert("失败");
            }, 2000);
            window.onerror = function () {
                clearInterval(_timeOut);
                script = document.createElement("script");
                script.onreadystatechange = function () {
                    if (/loaded|complete/i.test(this.readyState)) {alert("成功")}
                };
                script.type = "text/javascript";
                script.src = jsUrl;
                document.getElementsByTagName("head")[0].appendChild(script);
                return false;
            };
        }
        script.src = jsUrl;
        head.appendChild(script);

    终于解决关键问题,可是这定时触发失败的时间又是一个问题,到底应该定多长时间为失败呢?经过测试一般js在100KB以内,2秒内完全可以载完??墒堑目墒羌偃缥募洗蠡蛘咄倏苏馊绾问呛??

    我们必须等文件载完方可判断是否失败,而且不管文件是否加载成功必须会触发readyState变化,这……经过反复修改终于完美出版此方法:

    function loadScript(jsUrl, callBack) {
        /*
         * 加载单个script并回调函数
         * jsUrl : js地址字符串
         * callBack:function(state,node) 回调函数(可?。﹕tate = ok|no;node为script节点
         * 原创:[email protected]
         * 作用:加载本地或者网络多个文本文件(除vbscript)大小不限并判断成功与否
         * 如有问题或者改进请通知,谢谢
         * */
        var _doc = document,
                script = _doc.createElement("script"),
                head = _doc.head || _doc.getElementsByTagName("head")[0] || _doc.documentElement;
        'function' != typeof callBack && (callBack = function(){});//确保有回调函数
        if ("onload" in script) {
            //非IE和IE9及以上支持onload、onerror事件
            script.type = "text/javascript";
            script.onload = function () {
                callBack.call(null,"ok",this);
            };
            script.onerror = function () {
                callBack.call(null,"no",this);
            };
        } else {
            var baseElement = head.getElementsByTagName("base")[0],_err = 0;
            script.language = "vbscript";
            //IE8及以下先把js当vbscript文件引入,如果触发window.onerror说明js有效。假如您的脚本也使用了window.onerror请使用监听方法替换以免冲突
            window.onerror = function(){
                _err = 1;
                return true;//忽略错误
            };
            script.attachEvent("onreadystatechange",function(){
                //vbscript成功载入将会先触发window.onerror
                if (/loaded|complete/i.test(script.readyState)) {
                    window.onerror = null;//清理监听事件
                    if(_err){
                        script.parentNode.removeChild(script);//移除vbscript节点
                        script = document.createElement("script");//再生成script节点并插入文档
                        script.attachEvent("onreadystatechange",function(){
                            if (/loaded|complete/i.test(script.readyState)) {
                                callBack.call(null, "ok", script);
                            }
                        });
                        script.type = "text/javascript";
                        script.src = jsUrl;
                        //IE6下script必须插入到base前,以防引起bug
                        baseElement ? head.insertBefore(script, baseElement) : head.appendChild(script);
                    }else{
                        callBack.call(null,"no",script);
                    }
                }
            });
        }
        script.src = jsUrl;//必须先赋值后生成,否则影响readyState值
        head.appendChild(script);
    }
    //调用
    loadScript("//www.tgpe.net/1/test.js?a=" + Math.random(),
        function (state,node) {
            alert("ok" == state ? "成功":"失败");
        }
    );

    最后希望您能测试有问题请通知我,谢谢!

    最后的最后我告诉你:它也是有一个小bug呢!假如在IE8以下你加载一个vbscript伪装成的js文件那也会误报哟!

     

    =========================假如需要加载多个js文件情况下请使用以下函数===============================

    function loadScripts(jsArray,callBack) {
        "use strict";
        /*
         * 按序加载多个script并回调函数
         * jsArray : 单个js地址字符串或者是js文件地址数组
         * callBack:function(state,node) 回调函数(可?。﹕tate = ok|no;node为script节点
         * 原创:[email protected]
         * 作用:加载本地或者网络多个文本文件(除vbscript)大小不限并判断成功与否
         * 如有问题或者改进请通知,谢谢
         * */
        var _doc = document,
                script,
                head = _doc.head || _doc.getElementsByTagName("head")[0] || _doc.documentElement,
                baseElement = head.getElementsByTagName("base")[0];
        function loadJs() {
            if(0 == jsArray.length){
                callBack.call(null,"ok",script);
                return;
            }
            var jsUrl = jsArray.shift(),_err = 0;
            script = _doc.createElement("script");
            if ("onload" in script) {
                script.type = "text/javascript";
                script.onload = function () {
                    loadJs();
                };
                script.onerror = function () {
                    callBack.call(null,"no",this);
                };
            } else {
                script.language = "vbscript";
                //IE8及以下先把js当vbscript文件引入,如果触发window.onerror说明js有效
                //假如您的脚本也使用了window.onerror请使用监听方法替换以免冲突
                window.onerror = function(){
                    _err = 1;
                    return true;//忽略错误
                };
                script.attachEvent("onreadystatechange",function(){
                    //vbscript成功载入将会先触发window.onerror
                    if (/loaded|complete/i.test(script.readyState)) {
                        window.onerror = null;//清理监听事件
                        if(_err){
                            script.parentNode.removeChild(script);//移除vbscript节点
                            script = document.createElement("script");//再生成script节点并插入文档
                            script.attachEvent("onreadystatechange",function(){
                                if (/loaded|complete/i.test(script.readyState)) {
                                    loadJs();
                                }
                            });
                            script.type = "text/javascript";
                            script.src = jsUrl;
                            //IE6下script必须插入到base前,以防引起bug
                            baseElement ? head.insertBefore(script, baseElement) : head.appendChild(script);
                        }else{
                            callBack.call(null,"no",script);
                        }
                    }
                });
            }
            script.src = jsUrl;
            head.appendChild(script);
        }
        '[object Array]' != Object.prototype.toString.call(jsArray) && (jsArray = [jsArray]);//确保参数为数组
        'function' != typeof callBack && (callBack = function(){});//确保有回调函数
        loadJs();
    }
    //调用
    loadScripts(["//www.tgpe.net/1/test.js","//www.tgpe.net/1/jquery-easyui.js","//www.tgpe.net/1/jquerd.js"],
        function (state,node) {
            if("no"==state){
                alert(node.src+"文件加载失败!");
            }else{
                alert("成功!");
            }
        }
    );

    更新日期:2015-10-12 去除定时器机制

    关键词: javascript,异步加载   编辑时间: 2015-10-12 16:45:00

    • 感到高兴

      0

      高兴
    • 感到支持

      0

      支持
    • 感到搞笑

      0

      搞笑
    • 感到不解

      1

      不解
    • 感到谎言

      0

      谎言
    • 感到枪稿

      0

      枪稿
    • 感到震惊

      0

      震惊
    • 感到无奈

      0

      无奈
    • 感到无聊

      0

      无聊
    • 感到反对

      0

      反对
    • 感到愤怒

      0

      愤怒
    100%(2)
    0%(0)
    共有0 条评论 发言请遵守【相关规定

    网友评论

    会员头像
    发 表同步腾讯微博  匿名评论  验证码:  点击更新
    • 暂无评论
    关闭??? align=文章图片 article Pictrue
    • 基于koa2+mysql+vue2.0+Element阳光内容管理系统
    • 代码覆盖率工具 Istanbul 入门教程
    • 全栈工程师的武器——MEAN
    • 9款超炫的 CSS3 复选框(Checkbox)
    • 微信开发在线翻译功能
    • CSS3那些不为人知的高级属性
    • 给easyui的datebox添加清空事件
    • flash写字效果
    • kendoUI系列教程之DropDownList下拉菜单
    • kendoUI系列教程之datetimepicker日期时间选择
    • kendoUI系列教程之datepicker日期选择
    • kendoUI系列教程之combobox下拉列表框
    • kendoUI系列教程之colorpicker
    • kendoUI系列教程之calendar日历表
    • kendoUI系列教程之autocomplete自动补齐
    • kendo ui简介
  • 慈善基金进社区 点对点帮扶居民 2019-04-10
  • 三面悬崖的3197哨所 战士背饮用水要走"天梯" 2019-04-10
  • 习近平《在深入推动长江经济带发展座谈会上的讲话》单行本出版 2019-04-09
  • 女子在自家院子乘凉 被后山滚落千斤巨石砸死 2019-04-07
  • 很深刻。当今城市化基本出于房地资本的繁衍需要与维持粗陋GDP的无奈,越来越显露其反动性。 2019-04-03
  • 故都之秋,惊艳了整个华东文章中国国家地理网 2019-04-03
  • 中国虚拟现实创新创业大赛南昌赛区颁奖仪式举行 2019-03-31
  • 邯郸“廉政诊所”筑起基层首道廉政防线 2019-03-31
  • 蔡英文,赖清德,李登辉,陈水扁..... 2019-03-24
  • 【北京海之沃车型报价】北京海之沃4S店车型价格 2019-03-22
  • 上海电影节第三日:电影市场热议产业新形势 2019-03-22
  • 特朗普雇佣资深律师应对涉俄调查 2019-03-18
  • 两部门:支持建设一批乡土经济活跃的农业产业强镇 2019-03-17
  • 法国总统马克龙首次访华 法国居民期待成果 2019-03-16
  • 七星彩开奖 天津时时彩全国开奖号码 新时时彩历史开奖 双色球复式82三红一蓝 幸运28技巧是什么 湖南彩票双色球一等奖 申彗星赌博 上诲时时乐开奖 北京赛车官网博狗 重庆时时彩开不了奖 牛彩网彩票论坛 多乐彩票案件 360浏览新浪彩票网 七乐彩走势图表 七乐彩3+1有奖吗 彩票网站哪个赔率最高