Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

动态插入脚本和样式 #22

Open
Checkson opened this issue Mar 5, 2019 · 0 comments
Open

动态插入脚本和样式 #22

Checkson opened this issue Mar 5, 2019 · 0 comments

Comments

@Checkson
Copy link
Owner

Checkson commented Mar 5, 2019

动态脚本

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

  • 通过src特性包含外部文件 (插入外部文件)
  • 用这个元素本身包含代码 (直接插入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页面中的元素的方法有两种:

  • 使用link元素用于包含来自外部的文件
  • 使用<style>元素用于指定嵌入样式

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浏览器。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant