大家在瀏覽網(wǎng)頁(yè)的時(shí)候,是否思考過(guò)這樣一個(gè)問(wèn)題:怎樣才能制作出一個(gè)網(wǎng)頁(yè)呢?制作出一個(gè)網(wǎng)頁(yè)是很簡(jiǎn)單的,只要知道什么是HTML并掌握HTML的基礎(chǔ)知識(shí)就可以制作出一個(gè)簡(jiǎn)單的網(wǎng)頁(yè),今天我就為講解HTML的入門(mén)及結(jié)構(gòu)組成。
一、什么是HTML?
1、在我們開(kāi)始學(xué)習(xí)HTML之前我們需要知道什么是HTML?
HTML的全稱為Hyper Text Markup Language,中文名稱為超文本標(biāo)記語(yǔ)言,閱覽方式為網(wǎng)頁(yè)瀏覽器,同時(shí)HTML也被稱為網(wǎng)頁(yè)。
2、一個(gè)簡(jiǎn)單的HTML文檔
二、HTML編輯器
我們?cè)诳梢允褂肨XT文本文檔或者專業(yè)的HTML編輯器來(lái)編輯HTML。
1、記事本
① 創(chuàng)建一個(gè)TXT文本
② 輸入HTML代碼
③ 點(diǎn)擊文件—另存為—輸入名稱+“html”的后綴名即可得到你的第一個(gè)HTML文件。
④ 然后雙擊這個(gè)文件運(yùn)行。
運(yùn)行結(jié)果
2、專業(yè)編輯器
① Sublime Text
② HBuilder
③ Adobe Dreamweaver
④ CoffeeCup HTML Editor
這其中我比較推薦HBuilder這款編輯器,界面簡(jiǎn)單,編輯起來(lái)很快。
三、HTML的組成部分
在上面的案例中我們可以看到HTML是由頭部(head)和身體(body)所組成的。
1、頭部(head)
通常包含標(biāo)題(title),也就是一個(gè)網(wǎng)頁(yè)的名稱
網(wǎng)頁(yè)標(biāo)題
2、身體(body)
body的部分是整個(gè)網(wǎng)頁(yè)的重要內(nèi)容部分,讓人一眼就瀏覽到這個(gè)網(wǎng)頁(yè)的內(nèi)容,可以插入文本、圖片、多媒體等內(nèi)容。
四、HTML元素
l HTML元素是指以開(kāi)始標(biāo)簽起始,以結(jié)束標(biāo)簽終止的元素:元素內(nèi)容即為開(kāi)始標(biāo)簽與結(jié)束標(biāo)簽之間的內(nèi)容。
l <head></head>、<body></body>、<p></p>、<h1></h2>等這些都是HTML元素,在上面的案例中就有六個(gè)元素。
l 也有部分元素只有開(kāi)始標(biāo)簽,例如<br>,以開(kāi)始標(biāo)簽的結(jié)束而結(jié)束。
五、HTML的屬性
l 一般來(lái)說(shuō)HTML的屬性就是HTML元素的屬性,屬性可以在元素中添加附加信息。
l 屬性總是以名稱/值對(duì)的形式出現(xiàn),比如:name=”value”。
l 屬性一般描述于開(kāi)始標(biāo)簽。
l style中會(huì)有更多的屬性。
六、HTML格式化
HTML可定義很多供格式化輸出的元素,比如粗體字和斜體字。
HTML文本格式化標(biāo)簽
標(biāo)簽 | 描述 |
<b> | 定義粗體文本 |
<em> | 定義著重文字 |
<i> | 定義斜體字 |
<small> | 定義小號(hào)字 |
<strong> | 定義加重語(yǔ)氣 |
<sub> | 定義下標(biāo)字 |
<sup> | 定義上標(biāo)字 |
<ins> | 定義插入字 |
<del> | 定義刪除字 |
運(yùn)行結(jié)果示意圖
HTML“計(jì)算機(jī)輸出”標(biāo)簽
標(biāo)簽 | 描述 |
<code> | 定義計(jì)算機(jī)代碼 |
<kdd> | 定義鍵盤(pán)碼 |
<samp> | 定義計(jì)算機(jī)代碼樣本 |
<var> | 定義變量 |
<pre> | 定義預(yù)格式文本 |
HTML引文、引用及標(biāo)簽定義
標(biāo)簽 | 描述 |
<abbr> | 定義縮寫(xiě) |
<address> | 定義地址 |
<bdo> | 定義文字方向 |
<blockquote> | 定義長(zhǎng)的引用 |
<q> | 定義短的引用語(yǔ) |
<cite> | 定義引用、引證 |
<dfn> | 定義一個(gè)定義項(xiàng)目 |
七、HTML超鏈接
超鏈接可以是圖片、文字、多媒體也可以是一個(gè)網(wǎng)址
示例:
結(jié)果:
點(diǎn)擊帶有下劃線的兩個(gè)字就可以進(jìn)入某度的網(wǎng)站
八、HTML CSS
1、CSS是一種層疊樣式表,可以修飾html元素的樣式并可以精確地進(jìn)行排版
2、CSS有三種方式:
l 內(nèi)部樣式,在HTML元素中使用“style”屬性
l 內(nèi)部樣式表,在頭部<head>區(qū)域使用<style>元素來(lái)包含CSS
l 外部引用,引用帶有后綴css的文件,示例:
html文檔
css文檔
如果你看到了這里,就說(shuō)明你已經(jīng)打開(kāi)了制作網(wǎng)頁(yè)的大門(mén)啦~
對(duì)于前端來(lái)說(shuō),HTML 都是最基礎(chǔ)的內(nèi)容。
今天,我們來(lái)了解一下 HTML 和網(wǎng)頁(yè)有什么關(guān)系,以及與 DOM 有什么不同。通過(guò)本講內(nèi)容,你將掌握瀏覽器是怎么處理 HTML 內(nèi)容的,以及在這個(gè)過(guò)程中我們可以進(jìn)行怎樣的處理來(lái)提升網(wǎng)頁(yè)的性能,從而提升用戶的體驗(yàn)。
不知你是否有過(guò)這樣的體驗(yàn):當(dāng)打開(kāi)某個(gè)瀏覽器的時(shí)候,發(fā)現(xiàn)一直在轉(zhuǎn)圈,或者等了好長(zhǎng)時(shí)間才打開(kāi)頁(yè)面……
此時(shí)的你,會(huì)選擇關(guān)掉頁(yè)面還是耐心等待呢?
這一現(xiàn)象,除了網(wǎng)絡(luò)不穩(wěn)定、網(wǎng)速過(guò)慢等原因,大多數(shù)都是由于頁(yè)面設(shè)計(jì)不合理導(dǎo)致加載時(shí)間過(guò)長(zhǎng)導(dǎo)致的。
我們都知道,頁(yè)面是用 HTML/CSS/JavaScript 來(lái)編寫(xiě)的。
HTML由一系列的元素組成,通常稱為HTML元素。HTML 元素通常被用來(lái)定義一個(gè)網(wǎng)頁(yè)結(jié)構(gòu),基本上所有網(wǎng)頁(yè)都是這樣的 HTML 結(jié)構(gòu):
<html>
<head></head>
<body></body>
</html>
其中:
HTML 中的元素特別多,其中還包括可用于 Web Components 的自定義元素。
前面我們提到頁(yè)面 HTML 結(jié)構(gòu)不合理可能會(huì)導(dǎo)致頁(yè)面響應(yīng)慢,這個(gè)過(guò)程很多時(shí)候體現(xiàn)在<script>和<style>元素的設(shè)計(jì)上,它們會(huì)影響頁(yè)面加載過(guò)程中對(duì) Javascript 和 CSS 代碼的處理。
因此,如果想要提升頁(yè)面的加載速度,就需要了解瀏覽器頁(yè)面的加載過(guò)程是怎樣的,從根本上來(lái)解決問(wèn)題。
瀏覽器在加載頁(yè)面的時(shí)候會(huì)用到 GUI 渲染線程和 JavaScript 引擎線程(更詳細(xì)的瀏覽器加載和渲染機(jī)制將在第 7 講中介紹)。其中,GUI 渲染線程負(fù)責(zé)渲染瀏覽器界面 HTML 元素,JavaScript 引擎線程主要負(fù)責(zé)處理 JavaScript 腳本程序。
由于 JavaScript 在執(zhí)行過(guò)程中還可能會(huì)改動(dòng)界面結(jié)構(gòu)和樣式,因此它們之間被設(shè)計(jì)為互斥的關(guān)系。也就是說(shuō),當(dāng) JavaScript 引擎執(zhí)行時(shí),GUI 線程會(huì)被掛起。
以網(wǎng)易云課堂官網(wǎng)為例,我們來(lái)看看網(wǎng)頁(yè)加載流程。
(1)當(dāng)我們打開(kāi)官網(wǎng)的時(shí)候,瀏覽器會(huì)從服務(wù)器中獲取到 HTML 內(nèi)容。
(2)瀏覽器獲取到 HTML 內(nèi)容后,就開(kāi)始從上到下解析 HTML 的元素。
(3)<head>元素內(nèi)容會(huì)先被解析,此時(shí)瀏覽器還沒(méi)開(kāi)始渲染頁(yè)面。
我們看到<head>元素里有用于描述頁(yè)面元數(shù)據(jù)的<meta>元素,還有一些<link>元素涉及外部資源(如圖片、CSS 樣式等),此時(shí)瀏覽器會(huì)去獲取這些外部資源。除此之外,我們還能看到<head>元素中還包含著不少的<script>元素,這些<script>元素通過(guò)src屬性指向外部資源。
(4)當(dāng)瀏覽器解析到這里時(shí)(步驟 3),會(huì)暫停解析并下載 JavaScript 腳本。
(5)當(dāng) JavaScript 腳本下載完成后,瀏覽器的控制權(quán)轉(zhuǎn)交給 JavaScript 引擎。當(dāng)腳本執(zhí)行完成后,控制權(quán)會(huì)交回給渲染引擎,渲染引擎繼續(xù)往下解析 HTML 頁(yè)面。
(6)此時(shí)<body>元素內(nèi)容開(kāi)始被解析,瀏覽器開(kāi)始渲染頁(yè)面。
在這個(gè)過(guò)程中,我們看到<head>中放置的<script>元素會(huì)阻塞頁(yè)面的渲染過(guò)程:把 JavaScript 放在<head>里,意味著必須把所有 JavaScript 代碼都下載、解析和解釋完成后,才能開(kāi)始渲染頁(yè)面。
到這里,我們就明白了:如果外部腳本加載時(shí)間很長(zhǎng)(比如一直無(wú)法完成下載),就會(huì)造成網(wǎng)頁(yè)長(zhǎng)時(shí)間失去響應(yīng),瀏覽器就會(huì)呈現(xiàn)“假死”狀態(tài),用戶體驗(yàn)會(huì)變得很糟糕。
因此,對(duì)于對(duì)性能要求較高、需要快速將內(nèi)容呈現(xiàn)給用戶的網(wǎng)頁(yè),常常會(huì)將 JavaScript 腳本放在<body>的最后面。這樣可以避免資源阻塞,頁(yè)面得以迅速展示。我們還可以使用defer/async/preload等屬性來(lái)標(biāo)記<script>標(biāo)簽,來(lái)控制 JavaScript 的加載順序。
百度首頁(yè)
對(duì)于百度這樣的搜索引擎來(lái)說(shuō),必須要在最短的時(shí)間內(nèi)提供到可用的服務(wù)給用戶,其中就包括搜索框的顯示及可交互,除此之外的內(nèi)容優(yōu)先級(jí)會(huì)相對(duì)較低。
瀏覽器在渲染頁(yè)面的過(guò)程需要解析 HTML、CSS 以得到 DOM 樹(shù)和 CSS 規(guī)則樹(shù),它們結(jié)合后才生成最終的渲染樹(shù)并渲染。因此,我們還常常將 CSS 放在<head>里,可用來(lái)避免瀏覽器渲染的重復(fù)計(jì)算。
我們知道<p>是 HTML 元素,但又常常將<p>這樣一個(gè)元素稱為 DOM 節(jié)點(diǎn),那么 HTML 和 DOM 到底有什么不一樣呢?
根據(jù) MDN 官方描述:文檔對(duì)象模型(DOM)是 HTML 和 XML 文檔的編程接口。
也就是說(shuō),DOM 是用來(lái)操作和描述 HTML 文檔的接口。如果說(shuō)瀏覽器用 HTML 來(lái)描述網(wǎng)頁(yè)的結(jié)構(gòu)并渲染,那么使用 DOM 則可以獲取網(wǎng)頁(yè)的結(jié)構(gòu)并進(jìn)行操作。一般來(lái)說(shuō),我們使用 JavaScript 來(lái)操作 DOM 接口,從而實(shí)現(xiàn)頁(yè)面的動(dòng)態(tài)變化,以及用戶的交互操作。
在開(kāi)發(fā)過(guò)程中,常常用對(duì)象的方式來(lái)描述某一類事物,用特定的結(jié)構(gòu)集合來(lái)描述某些事物的集合。DOM 也一樣,它將 HTML 文檔解析成一個(gè)由 DOM 節(jié)點(diǎn)以及包含屬性和方法的相關(guān)對(duì)象組成的結(jié)構(gòu)集合。
我們常見(jiàn)的 HTML 元素,在瀏覽器中會(huì)被解析成節(jié)點(diǎn)。比如下面這樣的 HTML 內(nèi)容:
<html>
<head>
<title>標(biāo)題</title>
</head>
<body>
<a href='xx.com'>我的超鏈接</a>
<h1>頁(yè)面第一標(biāo)題</h1>
</body>
</html>
打開(kāi)控制臺(tái) Elements 面板,可以看到這樣的 HTML 結(jié)構(gòu),如下圖所示:
在瀏覽器中,上面的 HTML 會(huì)被解析成這樣的 DOM 樹(shù),如下圖所示:
我們都知道,對(duì)于樹(shù)狀結(jié)構(gòu)來(lái)說(shuō),常常使用parent/child/sibling等方式來(lái)描述各個(gè)節(jié)點(diǎn)之間的關(guān)系,對(duì)于 DOM 樹(shù)也不例外。
舉個(gè)例子,我們常常會(huì)對(duì)頁(yè)面功能進(jìn)行抽象,并封裝成組件。但不管怎么進(jìn)行整理,頁(yè)面最終依然是基于 DOM 的樹(shù)狀結(jié)構(gòu),因此組件也是呈樹(shù)狀結(jié)構(gòu),組件間的關(guān)系也同樣可以使用parent/child/sibling這樣的方式來(lái)描述。同時(shí),現(xiàn)在大多數(shù)應(yīng)用程序同樣以root為根節(jié)點(diǎn)展開(kāi),我們進(jìn)行狀態(tài)管理、數(shù)據(jù)管理也常常會(huì)呈現(xiàn)出樹(shù)狀結(jié)構(gòu)。
我們知道,瀏覽器中各個(gè)元素從頁(yè)面中接收事件的順序包括事件捕獲階段、目標(biāo)階段、事件冒泡階段。其中,基于事件冒泡機(jī)制,我們可以實(shí)現(xiàn)將子元素的事件委托給父級(jí)元素來(lái)進(jìn)行處理,這便是事件委托。
如果我們?cè)诿總€(gè)元素上都進(jìn)行監(jiān)聽(tīng)的話,則需要綁定三個(gè)事件;(假設(shè)頁(yè)面上有a,b,c三個(gè)兄弟節(jié)點(diǎn))
function clickEventFunction(e) {
console.log(e.target === this); // logs `true`
// 這里可以用 this 獲取當(dāng)前元素
}
// 元素a,b,c綁定
element2.addEventListener("click", clickEventFunction, false);
element5.addEventListener("click", clickEventFunction, false);
element8.addEventListener("click", clickEventFunction, false);
使用事件委托,可以通過(guò)將事件添加到它們的父節(jié)點(diǎn),而將事件委托給父節(jié)點(diǎn)來(lái)觸發(fā)處理函數(shù):
function clickEventFunction(event) {
console.log(e.target === this); // logs `false`
// 獲取被點(diǎn)擊的元素
const eventTarget = event.target;
// 檢查源元素`event.target`是否符合預(yù)期
// 此處控制廣告面板的展示內(nèi)容
}
// 元素1綁定
element1.addEventListener("click", clickEventFunction, false);
這樣能解決什么問(wèn)題呢?
常見(jiàn)的使用方式主要是上述這種列表結(jié)構(gòu),每個(gè)選項(xiàng)都可以進(jìn)行編輯、刪除、添加標(biāo)簽等功能,而把事件委托給父元素,不管我們新增、刪除、更新選項(xiàng),都不需要手動(dòng)去綁定和移除事件。
如果在列表數(shù)量?jī)?nèi)容較大的時(shí)候,對(duì)成千上萬(wàn)節(jié)點(diǎn)進(jìn)行事件監(jiān)聽(tīng),也是不小的性能消耗。使用事件委托的方式,我們可以大量減少瀏覽器對(duì)元素的監(jiān)聽(tīng),也是在前端性能優(yōu)化中比較簡(jiǎn)單和基礎(chǔ)的一個(gè)做法。
注意:
我們了解了 HTML 的作用,以及它是如何影響瀏覽器中頁(yè)面的加載過(guò)程的,同時(shí)還介紹了使用 DOM 接口來(lái)控制 HTML 的展示和功能邏輯。我們了解了DOM解析事件委托等相關(guān)概念。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>無(wú)標(biāo)題文檔</title> </head> <body> // 頁(yè)面源代碼內(nèi)容 </body> </html>
動(dòng)手小練習(xí):
1.試著默寫(xiě)HTML基本結(jié)構(gòu)
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。