Checkson / blog

Checkson个人博客
12 stars 3 forks source link

动态插入脚本和样式 #22

Open Checkson opened 5 years ago

Checkson commented 5 years ago

动态脚本

总所周知,使用<script>元素可以向页面中插入JavaScript代码,具体有两种方式:

定义

动态脚本,一般指的是在页面加载时不存在,但将来的某一时刻通过修改DOM动态添加的脚本。

1. 加载外部JavaScript文件

入门版

function loadScript (url) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    document.body.appendChild(script);
}

有人就会问,那我怎么监听这个动态脚本是否加载完成了?不急,还有进阶版嘛

进阶版

function loadScript (url, callback) {
    var script = document.createElement('script')
    script.type = 'text/javascript';
    if (script.readyState) {    // 针对IE
        script.onreadystatechange = function () {
            if (script.readyState == 'loaded' || script.readyState == 'complete') {
                script.onreadystatechange = null;
                callback();
            }
        }
    } else {                    // 针对其他浏览器
        script.onload = function () {
            callback();
        }
    }
    script.src = url;
    document.body.appendChild(script);
}

简单说明一下,script.readyState在除IE下的浏览器输出都是 undefined 的,而 loaded 是代表数据加载完成,complete 是代表数据已经准备好了。这两个状态在不同的IE下表现又不一致,时而出现前者又不出现后者,时而出现后者又不出现前者,所以上面写法最保险了。

2. 直接在script标签插入JavaScript代码

入门版

function loadStriptString (code) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.appendChild(document.createTextNode(code));
    document.body.appendChild(script);
}

上述代码在高级版本的浏览器中能正常运行,但在IE会报错。IE将<script>视为一个特殊的元素,不允许DOM访问其子节点。不过,可以使用<script>元素的text属性来制定JavaScript代码。请看进阶版

进阶版

function loadStriptString (code) {
    var script = document.createElement('script');
    script.type = 'text/javascript';
    try {
        script.appendChild(document.createTextNode(code));
    } catch (e) {
        script.text = code;
    }
    document.body.appendChild(script);
}

特意说明一下,以上代码引用了3次 document,进行了3次全局变量查找,我们可以在函数内第一句代码前加入 var doc = document;,以后引用 doc 变量来替代 document 就可以了,减少全局变量查找。(请读者自行修改)

动态样式

类似动态脚本,能够把CSS样式动态包含到HTML页面中的元素的方法有两种:

1. 使用link包含外部文件

常用版

function loadStyles (url) {
    var link = document.createElement('link');
    link.rel = 'stylesheet';
    link.type = 'text/css';
    link.href = url;
    var head = document.head || document.getElementsByTagName('head')[0];
    head.appendChild(link);
}

需要注意的是,必须将<link>元素添加到<head>元素上而不是<body>元素上,才能保证在所有浏览器中的行为一致。

2. 使用<style>元素包含嵌入的CSS

常用版

function loadStyleString (css) {
    var style = document.createElement('style');
    style.type = 'text/css';
    try {
        style.appendChild(document.createTextNode(css));
    } catch (e) {
        style.styleSheet.cssText = css;
    }
    var head = document.head || document.getElementsByTagName('head')[0];
    head.appendChild(style);
}

这里也运用了try catch语句,为了兼容IE浏览器。