日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

动态引入js只能生效一次_动态插入的script脚本执行时间

發布時間:2025/3/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态引入js只能生效一次_动态插入的script脚本执行时间 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在一些場景我們會動態插入script標簽加載js。

譬如某個js文件不是很重要,并不是整個頁面需要的腳本,可能只是某個功能需要的,這個功能可能是用戶點擊了某個按鈕才觸發,入口比較深。且和你頁面本身的結構不同類,譬如你是基于react的頁面,這個功能的js是jquery插件。這種js文件我一般采用動態加載方式引入。

如果你用js動態插入script,那么它什么時候執行呢,如果插入多個script,且之間有依賴關系,是否先插入的script先執行呢?

答案是:不是

demo案例

js-exec.js:動態插入2個script到頁面中,test1.js中定義了一個全局變量obj,test2.js加載完成后的onload事件中會去使用這個變量obj。test1.js和test2.js都在打印了信息方便查看執行順序

var?getReadyForEditor?=?()?=>?{
??console.log(obj.foo)
}

var?editorJs?=?document.createElement("script")
editorJs.src?=?"./test1.js"
document.body.appendChild(editorJs)

var?editorJs2?=?document.createElement("script")
editorJs2.src?=?"./test2.js"
editorJs2.onload?=?getReadyForEditor
document.body.appendChild(editorJs2)?

test1.js: 控制臺打印1,并且定義了obj變量

console.log(1)
var?obj?=?{
??foo:?'foo'
}

test2.js: 控制臺打印2。

console.log(2)

執行

通過不斷刷新,發現大概率是按照test1、test2的順序執行,但是也有一部分是先執行test2再執行test1:

由截圖可見,網絡請求順序是按照script插入的順序,先插入到dom的先請求,但是請求時間不一樣,test2比test1的請求時間短,內容先返回。看現象貌似結論是:資源加載完成時執行,因此資源加載先完成的先執行

猜測

我們都知道如果是非動態插入的script,是按照在html里出現的順序執行的,但是現在動態插入的腳本,雖然先插入的script位于html的前面,后插入的在后面,但是執行順序卻沒有按這個順序來。

是不是因為瀏覽器不知道在一個script標簽插入后還有沒有下一個要插入,所以沒法按順序執行呢?那么我們一次性插入這2個標簽會怎樣?

var?getReadyForEditor?=?()?=>?{
??console.log(obj.foo)
}

var?editorJs?=?document.createElement("script")
editorJs.src?=?"./test1.js"
//?document.body.appendChild(editorJs)

var?editorJs2?=?document.createElement("script")
editorJs2.src?=?"./test2.js"
editorJs2.onload?=?getReadyForEditor
//?document.body.appendChild(editorJs2)?

var?docFrag?=?document.createDocumentFragment()
docFrag.appendChild(editorJs)?//?Note?that?this?does?NOT?go?to?the?DOM
docFrag.appendChild(editorJs2)
document.body.appendChild(docFrag)?

通過createDocumentFragment創造文檔片段,然后一次插入,這樣瀏覽器該知道順序了吧。

但是結果依舊沒變。猜想錯誤!

真相

MDN文檔:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script

原來是因為瀏覽器對動態插入的script標簽,默認設置的是async。(各瀏覽器有區別)

我們知道async作用的js腳本時沒有順序的,異步加載,加載后執行。

因此特性,所以還有個defer,defer是異步加載,按script在文檔中的順序執行。

那我們的測試demo試一下,打印出來的async果真是true

如何讓動態插入的script標簽按插入順序執行

既然問題出在async上,那么創建script標簽時把他設置為false就好。

var?editorJs?=?document.createElement("script")
editorJs.src?=?"./test1.js"
editorJs.async?=?false
document.body.appendChild(editorJs)

var?editorJs2?=?document.createElement("script")
editorJs2.src?=?"./test2.js"
editorJs2.onload?=?getReadyForEditor
editorJs2.async?=?false
document.body.appendChild(editorJs2)?

再觀察,即使test2比test1先加載完,也會等待test1執行完在執行了~

總結

以上是生活随笔為你收集整理的动态引入js只能生效一次_动态插入的script脚本执行时间的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。