前言
JavaScript是瀏覽器的內建指令碼語言。當網頁中嵌入了JavaScript指令碼,瀏覽器載入網頁時,就會執行指令碼,從而操作瀏覽器,實現各種動態效果
JavaScript程式碼嵌入網頁的方法
1、<script>
元素直接嵌入程式碼
<script type="text/javascript">
function sayHello() {
alert("hello!");
}
</script>
2、<script>
元素載入外部指令碼
<script type="text/javascript" src="example.js"></script>
<script>
標籤相關屬性
type屬性
-
<script>
標籤預設就是JavaScript程式碼,嵌入javascript指令碼時,type屬性可以省略 - 如果type屬性的值,瀏覽器不認識,就不會執行其中的程式碼,所以可以在
<script>
標籤中嵌入任意的文字內容,只要加上一個瀏覽器不認識的type屬性就行,瀏覽器不會執行也不會顯示它的內容,但是這個<script>
節點依然存在於DOM之中,可以使用<script>
節點的text屬性讀取它的內容
defer屬性
<script src="a.js" defer></script>
<script src="b.js" defer></script>
defer屬性的執行流程:
- 瀏覽器開始解析HTML網頁
- 解析過程中,發現帶有defer屬性的
<script>
元素 - 瀏覽器繼續往下解析HTML網頁,同時並行下載
<script>
元素載入的外部指令碼 - 瀏覽器完成解析HTML網頁,此時再回過頭執行已經下載完成的指令碼
需要注意:
- 非同步載入資源
- 按照順序執行指令碼
- 使用defer載入的外部指令碼不應該使用document.write方法
async屬性
<script src="a.js" async></script>
<script src="b.js" async></script>
async屬性的執行流程:
- 瀏覽器開始解析HTML網頁
- 解析過程中,發現帶有async屬性的
<script>
標籤 - 瀏覽器繼續往下解析HTML網頁,同時並行下載
<script>
標籤中的外部指令碼 - 指令碼下載完成,瀏覽器暫停解析HTML網頁,開始執行下載的指令碼
- 指令碼執行完畢,瀏覽器恢復解析HTML網頁
需要注意:
- 非同步載入資源
- 並不會按照順序執行JS,誰先下載完,誰就先執行
- 使用async載入的外部指令碼不應該使用document.write方法
async和defer屬性歸納
- 都能解決“阻塞效應”
- 都是非同步載入資源,但執行順序不一樣
- 如果指令碼之間沒有依賴關係,就使用async屬性,如果指令碼之間有依賴關係,就使用defer屬性
Load事件
- 瀏覽器已經載入了所有依賴的資源,包括圖片樣式表等
- 可以在load事件觸發時獲得圖片的大小
- 繫結到window,
window.addEventListener("load",ready);
DOMContentLoaded事件
- 瀏覽器已經完全載入了HTML,DOM樹已經構建完畢
- JS可以訪問所有DOM節點,但是圖片和樣式表等外部資源可能沒有下載完畢
- 繫結到document:
document.addEventListener("DOMContentLoaded",ready);
涉及到async的知識點
- 非同步async指令碼一定會在頁面load事件之前執行
- 非同步async指令碼可能會在DOMContentLoaded事件觸發之前或者之後執行
動態生成指令碼
[`a.js`, `b.js`].forEach(src => {
const script = document.createElement(`script`);
script.src = src;
script.async = false;
document.head.appendChild(script);
});
- 不會阻塞頁面渲染
- async設定為false可以保證b.js在a.js後面執行
- 在這段程式碼後面載入的指令碼檔案,會等在b.ja執行完成後再執行
相關知識點總結
- 包含在
<script>
標籤內部的JavaScript程式碼,將被從上到下一次解析 - 無論以哪種方式嵌入程式碼,只要不存在defer和async屬性,瀏覽器都會按照
<Script>
標籤在頁面中出現的先後順序對它們進行解析 - 載入外部指令碼的優點:可維護性、可快取、適應未來
-
<script>
放在底部的原因1、避免“阻塞效應”。2、避免,在DOM結構生成之前呼叫DOM節點,而產生錯誤