寫個js/css動態載入的JavaScript外掛

關愛單身狗發表於2017-01-19

由於現在手上專案沒用到jQuery,以及希望能動態載入js/css
所以就寫了動態載入的指令碼
原理簡介:
通過給定的url引數中js/css檔案的字尾動態外掛節點
通過引數繫結新增到的父級節點
繫結節點載入onload 和 onerror事件執行檔案載入成功或失敗事件

1.JavaScript建立節點新增到body或head

新增js的程式碼:

var n = document.createElement("script");
n.setAttribute("type", "text/javascript");
n.setAttribute("src", i);
document.body.appendChild(n); 
document.head.appendChild(n);

寫個用來動態新增節點js的程式碼:

/*
es6 中 函式設定預設引數可以使用 例:function 函式名(變數= 預設值) {...}
如果想要相容可以使用 例:function 函式名(變數) {if(變數==undefined){變數= 預設值}....}
*/
function cr_node(i, l = "body") { //建立節點並新增
    t = i.split(".").reverse()[0];//獲取字尾
    var n = null;
    if (t == "js") {//字尾判斷
        n = document.createElement("script");
        n.setAttribute("type", "text/javascript");
        n.setAttribute("src", i);
    } else if (t == "css") {
        n = document.createElement("link");
        n.setAttribute("rel", "stylesheet");
        n.setAttribute("href", i);
    }
    if (n != null) {
        if (l == "body") {
            document.body.appendChild(n);
        } else if (l == "head") {
            document.head.appendChild(n);
        } else {
            l.appendChild(n);
        }
    }
    return n;
}

使用示例:

//新增bootstrap樣式
cr_node("http://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css","head")

//預設新增jquery到<body>...</body>
cr_node("http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js");

//新增jquery到<head>...</head>
cr_node("http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js","head");

//新增jquery到<div id="id">...</div>
cr_node("http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js",document.getElementById("id"))

2.新增繫結事件函式

新增單個節點並繫結 事件

function cr_node(i, l = "body") {....}
function addNode(o, c = undefined) { //單個新增
    var n = null;
    if(typeof(o) == "object") {
        n = cr_node(o.src, (o.parent ? o.parent : "body"));
        if(typeof(o.load) == "function") {
            n.onload = o.load; //繫結載入事件
        }
        if(typeof(o.err) == "function") {
            n.onerror = o.err; //繫結錯誤事件
        }
    } else if(typeof(o) == "string") {
        n = cr_node(o); //直接新增節點
        if(typeof(c) == "function") {
            n.onerror = n.onload = c; //繫結載入事件
        }
    }
}

使用說明:

//直接使用
addNode("http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js",function(){...});
//完整使用
addNode({
    "src": "http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js",
    "load": function() {
        console.log("載入成功");
        console.log($("body").html());
    },
    "err":function() {
        console.log("載入失敗");
    },
    "parent": document.getElementById("id")//不寫預設是body
})

3.嘗試寫個批量新增的函式

如果僅僅是新增可以使用以下函式:

function addNodes(o, index = 0) { //多個新增
    if (o.src.length > index && typeof(o.src) == "object" && o.src.length > 0) {
        var n = cr_node(o.src[index], o.parent);
        if (o.src.length - 1 == index && typeof(o.load) == "function") {
            n.onerror = n.onload = o.load;
        } else {
            n.onerror = n.onload = function() {
                addNodes(o, index + 1);
            }
        }
    }
}

使用示例:

addNodes({
 "src":["http://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.css","http://cdn.bootcss.com/jquery/3.1.1/jquery.min.js","http://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.min.js","http://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js"],
"parent":"head", 
"load":function(){
 console.log(1111);
   console.log($("body").html());
 }
})

動態插入節點載入js/css,其實是非同步載入,所以在批量載入中我使用類似同步載入的辦法來保證所有檔案載入完成後呼叫函式,防止非同步造成檔案為讀取完就執行導致的報錯
如果大家也有好的辦法歡迎留言。


相關文章