這里是云端源想IT,幫你輕松學IT”
嗨~ 今天的你過得還好嗎?
我們總是先揚起塵土
然后抱怨自己看不見
- 2024.04.17 -
JavaScript是一種輕量級的編程語言,通常用于網頁開發,以增強用戶界面的交互性和動態性。然而在HTML中,有多種方法可以嵌入和使用JavaScript代碼。
本文就帶大家深入了解如何在HTML中使用JavaScript。
要在HTML中使用JavaScript,我們需要使用<script>標簽。這個標簽可以放在<head>或<body>部分,但通常我們會將其放在<body>部分的底部,以確保在執行JavaScript代碼時,HTML文檔已經完全加載。
使用 <script> 標簽有兩種方式:直接在頁面中嵌入 JavaScript 代碼和包含外部 JavaScript 文件。
包含在 <script> 標簽內的 JavaScript 代碼在瀏覽器總按照從上至下的順序依次解釋。
所有 <script> 標簽都會按照他們在 HTML 中出現的先后順序依次被解析。
HTML 為 <script> 定義了幾個屬性:
1)async:可選。表示應該立即下載腳本,但不妨礙頁面中其他操作。該功能只對外部 JavaScript 文件有效。
如果給一個外部引入的js文件設置了這個屬性,那頁面在解析代碼的時候遇到這個<script>的時候,一邊下載該腳本文件,一邊異步加載頁面其他內容。
2)defer:可選。表示腳本可以延遲到整個頁面完全被解析和顯示之后再執行。該屬性只對外部 JavaScript 文件有效。
3)src:可選。表示包含要執行代碼的外部文件。
4)type:可選。表示編寫代碼使用的腳本語言的內容類型,目前在客戶端,type 屬性值一般使用 text/javascript。不過這個屬性并不是必需的,如果沒有指定這個屬性,則其默認值仍為text/javascript。
1.1 直接在頁面中嵌入JavaScript代碼
內部JavaScript是將JavaScript代碼放在HTML文檔的<script>標簽中。這樣可以將JavaScript代碼與HTML代碼分離,使結構更清晰,易于維護。
在使用<script>元素嵌入JavaScript代碼時,只須為<script>指定type屬性。然后,像下面這樣把JavaScript代碼直接放在元素內部即可:
<script type="text/javascript">
function sayHi(){
alert("Hi!");
}
</script>
如果沒有指定script屬性,則其默認值為text/javascript。
包含在<script>元素內部的JavaScript代碼將被從上至下依次解釋。在解釋器對<script>元素內部的所有代碼求值完畢以前,頁面中的其余內容都不會被瀏覽器加載或顯示。
在使用<script>嵌入JavaScript代碼的過程中,當代碼中出現"</script>"字符串時,由于解析嵌入式代碼的規則,瀏覽器會認為這是結束的</script>標簽??梢酝ㄟ^轉義字符“\”寫成<\/script>來解決這個問題。
1.2 包含外部 JavaScript 文件
外部JavaScript是將JavaScript代碼放在單獨的.js文件中,然后在HTML文檔中通過<script>標簽的src屬性引用這個文件。這種方法可以使代碼更加模塊化,便于重用和共享。
如果要通過<script>元素來包含外部JavaScript文件,那么src屬性就是必需的。這個屬性的值是一個指向外部JavaScript文件的鏈接。
<script type="text/javascript" src="example.js"></script>
與解析嵌入式JavaScript代碼一樣,在解析外部JavaScript文件(包括下載該文件)時,頁面的處理也會暫時停止。
注意:帶有src屬性的<script>元素不應該在其<script>和</script>標簽之間再包含額外的JavaScript代碼。如果包含了嵌入的代碼,則只會下載并執行外部腳本文件,嵌入的代碼會被忽略。
通過<script>元素的src屬性還可以包含來自外部域的JavaScript文件。它的src屬性可以是指向當前HTML頁面所在域之外的某個域中的完整URL。
<script type="text/javascript" src="http://www.somewhere.com/afile.js"></script>
于是,位于外部域中的代碼也會被加載和解析。
1.3 標簽的位置
在HTML中,所有的<script>標簽會按照它們出現的先后順序被解析。在不使用defer和async屬性的情況下,只有當前面的<script>標簽中的代碼解析完成后,才會開始解析后面的<script>標簽中的代碼。
通常,所有的<script>標簽應該放在頁面的<head>標簽中,這樣可以將外部文件(包括CSS和JavaScript文件)的引用集中放置。
然而,如果將所有的JavaScript文件都放在<head>標簽中,會導致瀏覽器在呈現頁面內容之前必須下載、解析并執行所有JavaScript代碼,這可能會造成明顯的延遲,導致瀏覽器窗口在加載過程中出現空白。
為了避免這種延遲問題,現代Web應用程序通常會將所有的JavaScript引用放置在<body>標簽中的頁面內容的后面。這樣做可以確保在解析JavaScript代碼之前,頁面的內容已經完全呈現在瀏覽器中,從而加快了打開網頁的速度。
JavaScript 解析過程包括兩個階段:預處理(也稱預編譯)和執行。
1、執行過程
HTML 文檔在瀏覽器中的解析過程是:按照文檔流從上到下逐步解析頁面結構和信息。
JavaScript 代碼作為嵌入的腳本應該也算做 HTML 文檔的組成部分,所以 JavaScript 代碼在裝載時的執行順序也是根據 <script> 標簽出現的順序來確定。
你是不是厭倦了一成不變的編程模式?想要突破自我,挑戰新技術想要突破自我,挑戰新技術?卻遲遲找不到可以練手的項目實戰?是不是夢想打造一個屬于自己的支付系統?那么,恭喜你,云端源想免費實戰直播——《微實戰-使用支付寶/微信支付服務,網站在線支付功能大揭秘》正在進行,點擊前往獲取源碼!云端源想
2、預編譯
當 JavaScript 引擎解析腳本時候,他會在與編譯期對所有聲明的變量和函數預先進行處理。當 JavaScript 解析器執行下面腳本時不會報錯。
alert(a); //返回值 undefined
var a = 1;
alert(a); //返回值 1
由于變量聲明是在預編譯期被處理的,在執行期間對于所有的代碼來說,都是可見的,但是執行上面代碼,提示的值是 undefined 而不是 1。
因為變量初始化過程發生在執行期,而不是預編譯期。在執行期,JavaScript 解析器是按照代碼先后順序進行解析的,如果在前面代碼行中沒有為變量賦值,則 JavaScript 解析器會使用默認值 undefined 。
由于第二行中為變量 a 賦值了,所以在第三行代碼中會提示變量 a 的值為 1,而不是 undefined。
fun(); //調用函數,返回值1
function fun(){
alert(1);
}
函數聲明前調用函數也是合法的,并能夠正確解析,所以返回值是 1。但如果是下面這種方式則 JavaScript 解釋器會報錯。
fun(); //調用函數,返回語法錯誤
var fun = function(){
alert(1);
}
上面的這個例子中定義的函數僅作為值賦值給變量 fun 。在預編譯期,JavaScript 解釋器只能夠為聲明變量 fun 進行處理,而對于變量 fun 的值,只能等到執行期時按照順序進行賦值,自然就會出現語法錯誤,提示找不到對象 fun。
總結:聲明變量和函數可以在文檔的任意位置,但是良好的習慣應該是在所有 JavaScript 代碼之前聲明全局變量和函數,并對變量進行初始化賦值。在函數內部也是先聲明變量,后引用。
通過今天的分享,相信大家已經對JavaScript在HTML中的應用有了一定的了解。這只是冰山一角,JavaScript的潛力遠不止于此。希望這篇文章能激發大家對編程的熱情,讓我們一起在編程的世界里探索更多的可能性!
我們下期再見!
END
文案編輯|云端學長
文案配圖|云端學長
內容由:云端源想分享
目開發中一些常用的es6知識,主要是為以后分享小程序開發、node+koa項目開發以及vueSSR(vue服務端渲染)做個前置鋪墊。
項目開發常用es6介紹
Module
Module即模塊的意思,在一些小項目中可能用不到這個概念。但是對于一些大型的、復雜的項目尤其在多人協作的情況下幾乎是必須的。
在 ES6 之前,最主要的有 CommonJS 和 AMD 兩種模塊化解決方案。前者用于服務器,后者用于瀏覽器。ES6 的出現實現了模塊功能,而且實現得相當簡單完全可以取代 CommonJS 和 AMD 規范,成為瀏覽器和服務器通用的模塊解決方案。
簡單的說ES6 模塊是通過export命令指定輸出的代碼,再通過import命令導入
下面我們直接通過代碼來演示:
<! DOCTYPE html > < html > < head lang = "en" > < meta charset = "UTF-8" > < title ></ title > </ head > < body > < script type = "module" > //index.html import * as util from "./js/scrpit.js" ; //用星號(*)指定一個對象,所有輸出值都加載在這個對象上面 util . func1 () //1 util . func2 () //2 console . log ( util . a == 3 ) //true </ script > </ body > </ html > //script.js export function func1 () { console . log ( 1 ) } export function func2 () { console . log ( 2 ) } export var a = 3 ;
可以看到body里面的script標簽與我們平常寫的稍有不同,加入了type="module"屬性,這樣瀏覽器才會知道這是一個 ES6 模塊。
當然,模塊的導入導出還可以有別的方式:
比如常用的導出模塊的兩種方式:
//script.js 方式1 export function func1 () { console . log ( 1 ) } export function func2 () { console . log ( 2 ) } export var a = 3 ; //script.js 方式2 function func1 () { console . log ( 1 ) } function func2 () { console . log ( 2 ) } var a = 3 ; export { func1 , func2 , a }
常用的導入模塊的兩種方式:
///方式1 import { func1 , func2 , a } from "./js/scrpit.js" ; func1 () //1 func2 () //2 console . log ( a == 3 ) //true ///方式2 import * as util from "./js/scrpit.js" ; util . func1 () //1 util . func2 () //2 console . log ( util . a == 3 ) //true
解構賦值
其實在模塊的導入中就已經用到了解構賦值。即按照一定模式,從數組和對象中提取值,并對變量進行賦值。
下面列舉一些簡單的示例,如需深入學習建議大家去學習阮一峰寫的es6入門哈
//情景1 let [ foo , [[ bar ], baz ]] = [ 1 , [[ 2 ], 3 ]]; foo // 1 bar // 2 baz // 3 //情景2 let [ , , third ] = [ "foo" , "bar" , "baz" ]; third // "baz" //情景3 let [ x , , y ] = [ 1 , 2 , 3 ]; x // 1 y // 3 //情景4 let [ head , ... tail ] = [ 1 , 2 , 3 , 4 ]; head // 1 tail // [2, 3, 4] //情景5 let [ x , y , ... z ] = [ 'a' ]; x // "a" y // undefined z // []
如果解構不成功,變量的值就等于undefined。
let [ foo ] = []; let [ bar , foo ] = [ 1 ];
以上兩種情況都屬于解構不成功,foo的值都會等于undefined。
另一種情況是不完全解構,即等號左邊的模式,只匹配一部分的等號右邊的數組。這種情況下,解構依然可以成功。
let [ x , y ] = [ 1 , 2 , 3 ]; x // 1 y // 2 let [ a , [ b ], d ] = [ 1 , [ 2 , 3 ], 4 ]; a // 1 b // 2 d // 4
上面兩個例子,都屬于不完全解構,但是可以成功。
如果等號的右邊不是數組(或者嚴格地說,不是可遍歷的結構),那么將會報錯。
// 報錯 let [ foo ] = 1 ; let [ foo ] = false ; let [ foo ] = NaN ; let [ foo ] = undefined ; let [ foo ] = null ; let [ foo ] = {};
解構賦值允許指定默認值。
注意,ES6 內部使用嚴格相等運算符(===),判斷一個位置是否有值。所以,只有當一個數組成員嚴格等于undefined,默認值才會生效。
let [ foo = true ] = []; foo // true let [ x , y = 'b' ] = [ 'a' ]; // x='a', y='b' let [ x , y = 'b' ] = [ 'a' , undefined ]; // x='a', y='b' let [ x = 1 ] = [ undefined ]; x // 1 let [ x = 1 ] = [ null ]; x // null //上面代碼中,如果一個數組成員是null,默認值就不會生效,因為null不嚴格等于undefined。
解構不僅可以用于數組,還可以用于對象。
let { foo , bar } = { foo : "aaa" , bar : "bbb" }; foo // "aaa" bar // "bbb"
對象的解構與數組有一個重要的不同。數組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。
let { bar , foo } = { foo : "aaa" , bar : "bbb" }; foo // "aaa" bar // "bbb" let { baz } = { foo : "aaa" , bar : "bbb" }; baz // undefined
如果變量名與屬性名不一致,必須寫成下面這樣。
let { foo : baz } = { foo : 'aaa' , bar : 'bbb' }; baz // "aaa" let obj = { first : 'hello' , last : 'world' }; let { first : f , last : l } = obj ; f // 'hello' l // 'world'
對象的解構也可以指定默認值。默認值生效的條件是,對象的屬性值嚴格等于undefined。
var { x = 3 } = { x : undefined }; x // 3 var { x = 3 } = { x : null }; x // null
模板字符串
傳統的 JavaScript 語言,輸出模板通常是這樣寫的:
$ ( '#result' ). append ( 'There are <b>' + basket . count + '</b> ' + 'items in your basket, ' + '<em>' + basket . onSale + '</em> are on sale!' );
上面這種寫法相當繁瑣不方便,ES6 引入了模板字符串解決這個問題。
$ ( '#result' ). append (` There are < b > $ { basket . count }</ b > items in your basket , < em > $ { basket . onSale }</ em > are on sale ! `);
即用反引號(Tab上面的按鍵)表示,如果模板字符串中嵌入變量,需要將變量名寫在${}之中。這樣就不需要使用大量的引號和加號,大大節約了開發時間。
注:在本地瀏覽器中使用模塊化需要配置服務環境,如果使用的是vscode編輯器可以安裝Open with live server插件,安裝完成后重啟編輯器就可以在.html文件上右鍵選擇Open with live server,然后瀏覽器輸入localhost:5500打開,端口號看編輯器最下方提示。如果是Hbuilder編輯器則需要配置一下web服務器,其它編輯器具體的可以百度一下哈。阿門~
關注我的頭條號,分享更多的技術學習文章,我自己是一名從事了多年開發的web前端老程序員,目前辭職在做自己的web前端私人定制課程,今年年初我花了一個月整理了一份最適合2019年學習的web前端學習干貨,各種框架都有整理,送給每一位前端小伙伴,想要獲取的可以關注我的頭條號并在后臺私信我:前端,即可免費獲取。
者:*5102
轉發鏈接:https://juejin.im/post/5e9f0bdce51d4546f5791989
*請認真填寫需求信息,我們會在24小時內與您取得聯系。