作為前端開發的小夥伴,一看到< script >標籤,是不是特別熟悉,因為前端開發的小夥們每天基本都會使用該標籤,但是仔細想想真的對< script >標籤瞭解嗎,它的的作用是什麼?它的位置應該放在哪?為啥這樣放?它有幾個屬性?每個屬性是幹什麼的?當然有些小夥伴已經知道個大概了,那麼我們們就帶著這幾個問題,來真正的瞭解一下熟悉的< script>標籤
1 < script > < /script >標籤的產生
我們經常使用的< script > < /script >標籤,大家都知道它是放在web核心語言HTML的標籤,當初在開發JavaScript的時候,遠景公司,為了解決一個重要的問題,就是如何做到JavaScript既能與HTML頁面共存,又不影響頁面的顯示效果,經過嘗試、糾錯和爭論,最終決定就是給web增加統一的指令碼支援。這些早期的很多做法也被保留了下來,並正式納入HTML規範當中。這就是< script>的產生 ,可以檢視《有關javascript的發展史》
2 < script > < /script >標籤的屬性
前端開發的小夥伴看這個熟悉的< script > < /script >標籤,能回答出來有幾個屬性嗎?可能聰明的小夥伴已經知道了,6個!沒錯就是6個。
- 1 type
- 2 src
- 3 defer
- 4 async
- 5 language
- 6 charset
大家對這個6個屬性,比較熟悉的可能依次是 type、src、async、defer,剩下的哪兩個可能就不太熟悉了,接下我們們就一起看一下這些屬性的用途,這6個屬性都是可選的。
2.1 type屬性。
前端小夥伴一下到type屬性就會想到type='text/javascript',其實type屬性預設值就是text/javascript,type是代替已經廢棄的language屬性,表示編寫程式碼使用的指令碼語言的內容型別(也可以成為MIME型別),雖然text/javascript和text/ecmascript都已經不被推薦使用了。但是大家一致用text/javascript,它還有其他屬性值如
application/x-javascriot(但是這個屬性會導致指令碼會被忽略)
application/javascript|applicationecmascript(考慮到瀏覽器相容,當然現在的瀏覽器不用考慮這些)2.2 src屬性
前端小夥伴對src的屬性的熟悉度不會低於type,因為現在js的開發一把都是放在js檔案中,這樣有利於集中開發和html文件清潔。
一般的情況下大家都會在src的屬性值中填寫一個相對路徑或者與當前域名一直的js路徑,因為這樣可以保證js檔案的來源和安全
某些情況下src的屬性值也可能是一個非同域名的地址,但是這個地址最好是自己知道並可以維護的地址,這樣可能會出現跨域指令碼攻擊,得到以下敏感資訊,來操作你的使用者資訊和賬戶金額等
大家看一下下面,會不會在控制檯輸出index.js字串
<html>
<head></head>
<body></body>
< script src='/index.js' >
console.log('index.js')
< /script >
</html>
複製程式碼
答案是不能,因為當使用了src外部資源的時候,瀏覽器就不會再解析執行< script>內部的程式碼塊了。
2.3 defer屬性
該屬性是html4.01為< script>標籤放在< head>中定義的
,在執行的時候不會影響到頁面構造。
//index.js
document.getElementById('root')
// index.html
<html>
<head>
< script src='/index.js' defer='defer' > < /script >
</head>
<body>
<div id ='root'></root>
</body>
</html>
複製程式碼
目的是告訴瀏覽器,可以立即下載js,但是延遲執行程式碼。
//index1.js
document.getElementById('root')
// index.html
//index2.js
document.getElementById('root')
// index.html
<html>
<head>
< script src='/index1.js' defer='defer' > < /script >
< script src='/index2.js' defer='defer' > < /script >
</head>
<body>
<div id ='root'></root>
</body>
</html>
複製程式碼
但是在HTML5的規範中要求指令碼按照它們出現的先後順序執行,因此第一個延遲執行的指令碼會先於第二個延遲執行,而這兩個指令碼會先於DOMContentLoaded事件執行。
實際上在不支援html5規範的瀏覽器上,延遲不一定會按照順序執行,也不一定會先於DOMContentLoaded事件執行,因此一個最好包含一個延遲指令碼
2.4 asycn 非同步指令碼
HTML5為< script>元素定義了async屬性。這個屬性與我們們看的上面的defer類似,async只適合外部指令碼檔案,告訴瀏覽器立即下載檔案,但於defer不同的async並不保證按照它們的出現先後順序執行
//index1.js
document.getElementById('root')
// index.html
//index2.js
document.getElementById('root')
// index.html
<!DOCTYPE html>
<html>
<head>
< script src='/index1.js' async > < /script >
< script src='/index2.js' async > < /script >
</head>
<body>
<div id ='root'></root>
</body>
</html>
複製程式碼
上面程式碼不確定 index1.js會先執行與index2.js,所以一定要保證index2.js不依賴與index1.js
2.5 language 屬性
該屬性已被廢棄,我們們大家只做瞭解,原來用於表示編寫怠慢使用的指令碼語言,(JavaScript、JavaScript1.2或者VBScript),但是大多數瀏覽器都會忽略這個屬性,因此沒有必要在使用了。
2.6 charset 屬性
可選。表示通過 src 屬性指定的程式碼的字符集。由於大多數瀏覽器會忽略它的值, 因此這個屬性很少有人用。
3 < script > < /script >的使用
3.1 嵌入使用,看程式碼
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id ='root'></root>
</body>
< script >
function sayHi(){
console.log('Hi')
}
< /script >
</html>
複製程式碼
包含著< script>內部的程式碼將被從上到下依次解釋,直譯器解釋一個函式的定義,然後將該定義儲存到自己的環境中。在直譯器對< script>元素內部的所有程式碼求值完畢以前,頁面中的其餘內容都不會被瀏覽器載入或者顯示。
在使用< script> 嵌入JavaScript程式碼時,不要在程式碼證任何地方出現“”字串。
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id ='root'></root>
</body>
< script >
function sayHi(){
console.log("< /script >"")
}
< /script >
</html>
複製程式碼
在瀏覽器中載入時會出現一個錯誤。
3.2 外部引入
<!DOCTYPE html>
<html>
<head>
< script src='/index1.js' async > < /script >
</head>
<body>
<div id ='root'></root>
</body>
</html>
複製程式碼
這種引入方式和嵌入的載入順序一樣,但是多了一步下載流程。但是他的好處是非常大的,
- 1可以統一集中的管理開發js
- 2相比嵌入式對html的整潔性有很大的太高
- 3 有利於分離開發
雖然有好處很大,但是也會出現以下載入位置或者載入順序的問題。
從上面的得到,在瀏覽器載入的時候,瀏覽器只會一心一意的載入解析js程式碼,其他的工作都會先放下,那麼問題來了。
<!DOCTYPE html>
<html>
<head>
< script src='/index1.js'> < /script >
</head>
<body>
<div id ='root'></root>
</body>
</html>
複製程式碼
如果index1.js程式碼解析的比較慢的話,頁面就會出現一個空白頁面。
如果index1.js程式碼解析的很快的話,由於index1.js中操作了某個dom其實,是無效的。
根據我們們瞭解的< script>標籤的 async 和 defer的屬性我們們可以解決,空白頁面的問題。
但是async 和 defer的屬性都有自己的侷限性
- 1 async 能夠保證不立即執行js程式碼,但是無法保證兩個外鏈程式碼的執行順序
- 2 defer 雖然規定了,能夠保證不立即執行js程式碼,保證外鏈程式碼的執行順序,但是一般瀏覽器不是這麼做的
那麼最好的解決方案是,需要把< script >標籤放在底部
這就是我們常用的< script>大家是不是有跟進一步的瞭解這這個標籤,歡迎大家補充不足的地方,歡迎留言點贊