zoukankan      html  css  js  c++  java
  • 如何动态加载js?

    第三方的js文件,自己写的js文件,js越来越多了怎么办?

    提出问题:

    1、js文件太多了,每个页面都写<script src="...">太麻烦。

    2、如果路径变化了,或者js名称变化了怎么办?每个页面都改一遍吗?

    3、如何约束js文件的加载顺序?a.js定义了一个函数,b.js要调用,但是b.js先加载了,a.js还没加载完成,造成函数未定义,无法调用。

    4、js文件的合并。开发阶段,js会分成多个文件,这样便于开发。但是成熟了之后会合并成一个文件。这样引用方式就会变化,原先引用一堆js,现在只需要引用一个js。同样不能每个页面都改一遍。

    5、加载js完毕之后,要可以执行回调函数。 

    解决问题:

    如何解决这些问题呢?我想到的办法是——动态加载js。就是通过js代码的方式来加载。

    在网上找了一些资料,最后确定借鉴 张经纬 的代码 http://www.zhangjingwei.com/archives/asynchronous-loading-js/

    其中这段代码挺符合我的需求。

    var loadscript =
    {
        $$:function(id){return document.getElementById(id)},
        tag:function(element){return document.getElementsByTagName(element)},
        ce:function(element){return document.createElement(element)},
        js:function(url,callback)
        {
            s = loadscript.ce('script');
            s.type = "text/javascript";
            s.onreadystatechange = ready;
            s.onerror = s.onload = callback;
            s.src = url;
            loadscript.tag('head')[0].appendChild(s);
            function ready(){
                if (s.readyState == 'loaded' || s.readyState == 'complete') {
                    callback();
                }
            };
        }
    }

    一开始把代码copy过来使用,在ie8和chrome里面都没有问题。既然没有问题那就用呗,虽然还不知道为啥要这么写代码。

    遇到新问题:

    但是没过多久就遇到了问题,在IE10里面,树、分页、表格等,都会多出来好几份?

    把IE10设置为兼容IE7的模式,就一切正常。看了是IE10的新特性照成的。那么到底是怎么回事呢?断点跟踪吧。

    弄了好久才发现,原来是js文件会被加载多次。

    为什么被加载了多次呢?原因在于 onreadystatechange 和 onload 。为什么这两个事件都调用了callback?为什么其他浏览器没事,IE10有事呢?

    根据断点跟踪得到了原因。

    原来 chrome只会触发 onload, 而不会触发onreadystatechange(不会进入断点)。

    而IE7只会触发 onreadystatechange,而不会触发onload。

    那么IE10呢?两个都会被触发。

    继续解决:

    一开始是想做一个标志位。做一个标志,如果callback了就不再次callback。但是实际效果有点不稳定,当然很可能是俺代码没处理好。

    于是还是换一种方法吧。老办法,判断浏览器类型。

    如果是IE10,那么只设置onload。然后,世界安静了。当然这里浏览器的类型判断还不完全。浏览器太多了,遇到不兼容的在考虑吧,俺js其实很烂的。

    var loadscript =
    {
        $$: function(id) { return document.getElementById(id); },
        tag: function(element) { return document.getElementsByTagName(element); },
        ce: function(element) { return document.createElement(element); },
        js: function(url, callback) {
            var s = loadscript.ce('script');
            s.type = "text/javascript";
            s.src = url;
            if (document.documentMode == 10 || document.documentMode == 9) {
                s.onerror = s.onload = loaded;
            } else {
                s.onreadystatechange = ready;
                s.onerror = s.onload = loaded;
            }
            loadscript.tag('head')[0].appendChild(s);
    
            function ready() { /*IE7.0/IE10.0*/
                if (s.readyState == 'loaded' || s.readyState == 'complete') {
                    callback();
                }
            }
    
            function loaded() { /*chrome/IE10.0*/
                callback();
            }
        }
    };

    小结:

    看最后的代码,是没啥特别的,重点在于理解原有代码,发现问题,解决问题的过程。

    下一步是如何管理js。还有js的客户端缓存、复用的问题。

  • 相关阅读:
    The Fifth Season Gym
    SuperHyperMarket Gym
    Far Manager Gym
    Game Map------Gym
    Happy Number
    Pursuing the Happiness
    Digit sum-----The Preliminary Contest for ICPC Asia Shanghai 2019
    Light bulbs------The Preliminary Contest for ICPC Asia Shanghai 2019
    P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm
    HDU 1203 I NEED A OFFER!
  • 原文地址:https://www.cnblogs.com/jyk/p/3078024.html
Copyright © 2011-2022 走看看