面試官:DTD 有什么作用?

DTD 有什么作用?
文檔類型聲明
在 HTML 中,文檔類型 doctype 的聲明是必要的。
在所有文檔的頭部,你都將會看到"" 的身影。
這個聲明的目的是防止瀏覽器在渲染文檔時,切換到我們稱為“怪異模式(兼容模式)”的渲染模式。
“" 確保瀏覽器按照最佳的相關(guān)規(guī)范進行渲染,而不是使用一個不符合規(guī)范的渲染模式。
什么是怪異模式?什么是標(biāo)準(zhǔn)模式?二者有什么差別(舉例)?產(chǎn)生的歷史原因是什么?使用時需要注意什么?
怪異模型
使用瀏覽器自己的方式解析執(zhí)行代碼,因為不同瀏覽器解析執(zhí)行的方式不一樣,所以稱之為怪異模式。
標(biāo)準(zhǔn)模型
按照 W3C 標(biāo)準(zhǔn)解析執(zhí)行代碼
瀏覽器解析時使用標(biāo)準(zhǔn)模式還是怪異模式,與網(wǎng)頁中的DTD聲明直接相關(guān),DTD聲明定義了標(biāo)準(zhǔn)文檔的類型(標(biāo)準(zhǔn)模式解析)文檔類型,會使瀏覽器使用相關(guān)的方式加載網(wǎng)頁并顯示,忽略DTD聲明,將使網(wǎng)頁進入怪異模式(quirks mode)。
產(chǎn)生的歷史原因?
是因為以前分了兩個,一個是網(wǎng)景,一個是 IE 瀏覽器,而W3C標(biāo)準(zhǔn)創(chuàng)建之后,為了兼容老代碼,老網(wǎng)站,所以采取了兩種模式。
二者都有什么差別
在怪異模式下,排版會模擬 Navigator 4 與 Internet Explorer 5 的非標(biāo)準(zhǔn)行為。為了支持在網(wǎng)絡(luò)標(biāo)準(zhǔn)被廣泛采用前,就已經(jīng)建好的網(wǎng)站,這么做是必要的。
在標(biāo)準(zhǔn)模式下,行為即(但愿如此)由 HTML 與 CSS 的規(guī)范描述的行為。
使用時需要注意什么?
1、盒模型:
在怪異模式下,盒模型為IE模型
height = border-top + border-bottom + padding-top + padding-bottom + content
width = border-left + border-right + padding-left + padding-right + content
而在W3C標(biāo)準(zhǔn)的盒模型
height = content
width = content
HTML5是什么?有哪些新特性?新增了哪些語義化標(biāo)簽?新增了哪些表單元素?
HTML5 是什么?
它是一個新版本的HTML語言,具有新的元素,屬性和行為,
它有更大的技術(shù)集,允許構(gòu)建更多樣化和更強大的網(wǎng)站和應(yīng)用程序。這個集合有時稱為HTML5和它的朋友們,不過大多數(shù)時候僅縮寫為一個詞 HTML5。
語義:能夠讓你更恰當(dāng)?shù)孛枋瞿愕膬?nèi)容是什么。 連通性:能夠讓你和服務(wù)器之間通過創(chuàng)新的新技術(shù)方法進行通信。 離線 & 存儲:能夠讓網(wǎng)頁在客戶端本地存儲數(shù)據(jù)以及更高效地離線運行。 多媒體:使 video 和 audio 成為了在所有 Web 中的一等公民。 2D/3D 繪圖 & 效果:提供了一個更加分化范圍的呈現(xiàn)選擇。 性能 & 集成:提供了非常顯著的性能優(yōu)化和更有效的計算機硬件使用。 設(shè)備訪問 Device Access:能夠處理各種輸入和輸出設(shè)備。 樣式設(shè)計: 讓作者們來創(chuàng)作更加復(fù)雜的主題吧!
有哪些新特性?
語義化標(biāo)簽 多媒體 video/audio 畫布 canvas 通信 websocket/webworker/Server-sent events 緩存 localStorage/sessionStorage 拖拽 drag/dragstart/dragover/dragleave/drop
新增了哪些語義化標(biāo)簽?
section 塊 article 文章 nav 導(dǎo)航 header 頭部 footer 頁腳 main 主要 aside 側(cè)邊欄
新增了哪些表單元素?
html5篇——新增表單元素和表單屬性
<form method="get" id="test">
<input type="text" name="name"/>
<input type="password" name="password"/>
<input type="submit" value="提交">
</form>
<input type="text" name="confirm" form="test">
<input type="email" name="email"/>
<input type="url" name="url"/>
<input type="number" name="number" min=2 max=100 step=5 value="15"/>
<input type="range" name="range" min=20 max=200 value="60"/>
<input type="date" name="date"/>
<input type="month" name="month"/>
<input type="week" name="week"/>
<input type="time" name="time"/>
<input type="datetime" name="datetime"/>
<input type="datetime-local" name="datetime-local"/>
<input type="search" name="search" result="s"/>
<input type="tel" name="tel" />
<input type="color" name="color"/>
<input type="text" name="name" pattern="[A-z0-9]{8}"/>
什么是HTML語義化?
單純的HTML代碼是不帶任何樣式的只是用來標(biāo)記這一段是標(biāo)題、這一塊是代碼、那一個是要強調(diào)的內(nèi)容等等,但是為什么我們只寫HTML在瀏覽器中不同的標(biāo)簽也是有不同的樣式呢?那是因為各個瀏覽器都自帶的有相應(yīng)標(biāo)簽的默認(rèn)樣式,為了方便在沒有設(shè)定樣式的情況下友好的展示頁面。良好的語義化代碼可以直接從代碼上就能看出來那一塊到底是要表達(dá)什么內(nèi)容。
為什么要使用HTML語義化標(biāo)簽?
1.標(biāo)簽語義化有助于構(gòu)架良好的HTML結(jié)構(gòu),有利于搜索引擎的建立索引、有助于爬蟲抓取更多的有效信息.簡單來說,試想在H1標(biāo)簽中匹配到的關(guān)鍵詞和在div中匹配到的關(guān)鍵詞搜索引擎會吧那個結(jié)果放在前面。 2.有利于不同設(shè)備的解析(屏幕閱讀器,盲人閱讀器等)滿是div的頁面這些設(shè)備如何區(qū)分那些是主要內(nèi)容優(yōu)先閱讀? 3.有利于構(gòu)建清晰的機構(gòu),有利于團隊的開發(fā)、維護。 4.提升用戶體驗,例如title、alt可用于解釋名詞或解釋圖片信息。 5.網(wǎng)頁加載慢導(dǎo)致CSS文件還未加載時(沒有CSS),頁面仍然清晰、可讀、好看。
語義化標(biāo)簽有啥缺陷
兼容性差
meta viewport 是做什么用的,怎么寫?
該meta標(biāo)簽的作用是讓當(dāng)前viewport的寬度等于設(shè)備的寬度
<meta name="viewport" content="width=device-width,initial-scale=1">
meta viewport 的6個屬性:
width設(shè)置layout viewport的寬度,為一個正整數(shù),或字符串"width-device"
initial-scale設(shè)置頁面的最大縮放值,為一個數(shù)字,可以帶小數(shù)
minimum-scale允許用戶的最小縮放值,為一個數(shù)字,可以帶小數(shù)
maximum-scale允許用戶的最大縮放值,為一個數(shù)字,可以帶小數(shù)
height設(shè)置layout viewport的高度,這個屬性并不重要,很少使用
user-scalable 是否允許用戶進行縮放,值為"no"或"yes"
使用 data-* 屬性有什么用?
是一類被稱為自定義數(shù)據(jù)屬性的屬性,它賦予我們在所有 HTML 元素上嵌入自定義數(shù)據(jù)屬性的能力,并可以通過腳本在 HTML 與 DOM 表現(xiàn)之間進行專有數(shù)據(jù)的交換。
通過 element.dataset[屬性名字] 獲取對應(yīng)的值。
<script>、<script async> 和 <script defer> 的區(qū)別。
<script>
不帶屬性,加載到 script 腳本立即下載執(zhí)行,阻塞后續(xù)渲染的執(zhí)行。
<script async>
與后續(xù)元素渲染異步執(zhí)行,亂序執(zhí)行,若js文件之間存在依賴關(guān)系,容易產(chǎn)生錯誤,
只適用于完全沒有依賴的文件,文檔解析過程中異步下載,下載完成之后立即執(zhí)行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="../vue.js" async></script>
<div id="app"
@once>
</div>
<script>
const vm = new Vue({
el: "#app",
data(){
return {
}
},
})
console.log("vm", vm)
</script>
</body>
</html>
你會發(fā)現(xiàn)控制臺報錯了:
Uncaught ReferenceError: Vue is not defined
<script defer>
與后續(xù)渲染異步執(zhí)行,延遲到界面文檔解析完成之后執(zhí)行,即為立即下載,延遲執(zhí)行。所有執(zhí)行均在DOMContentLoaded 事件觸發(fā)之前完成。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="../vue.js" defer></script>
<div id="app"
@once>
</div>
<script>
const vm = new Vue({
el: "#app",
data(){
return {
}
},
})
console.log("vm", vm)
</script>
</body>
</html>
最佳的解決方案
外部引用文件放在</body>之前執(zhí)行
<script/>放在<head/>與<body/>中的區(qū)別?
區(qū)別:加載順序的不同,在頁面加載之前下載,HTML加載順序是由上至下
<head/>:會在文檔加載前加載結(jié)束。
<body/>:不能保證哪個先加載結(jié)束(文檔?引用文件?)性能更優(yōu)
注:內(nèi)嵌的腳本也不要緊跟在<link>標(biāo)簽之后,否則會導(dǎo)致頁面阻塞去等待樣式表的下載。
白屏和FOUC是什么?
白屏
不同瀏覽器對 CSS 和 HTML 的處理方式不同,有的是等待 CSS 加載完成之后,對 HTML 元素進行渲染和展示。
白屏不是bug,而是由于瀏覽器的渲染機制。
FOUC
有的是先對 HTML 元素進行展示,然后等待 CSS 加載完成之后重新對樣式進行修改(無樣式內(nèi)容閃爍)
如何解決FOUC問題
盡量把 js 文件放在 <body> 標(biāo)簽后面引入,執(zhí)行。
瀏覽器的渲染機制
解析 DOM 樹 解析 CSSDOM 樹 有了 DOM 樹,CSSDOM 樹,進行渲染,形成 Render Tree layout 瀏覽器已經(jīng)能知道網(wǎng)頁中有哪些節(jié)點、各個節(jié)點的CSS定義以及他們的從屬關(guān)系,從而去計算出每個節(jié)點在屏幕中的位置 painting 繪制 reflow 回流 repaint 重繪 改變某個元素的背景色、文字顏色、邊框顏色等等不影響它周圍或內(nèi)部布局的屬性時,屏幕的一部分要重畫,但是元素的幾何尺寸沒有變。
什么是回流(影響布局的情況)
瀏覽器發(fā)現(xiàn)某個部分發(fā)生了點變化影響了布局,需要倒回去重新渲染,這個過程就是回流
什么是重繪(不影響布局的情況)
改變某個元素的背景色、文字顏色、邊框顏色等等不影響它周圍或內(nèi)部布局的屬性時,屏幕的一部分要重畫,但是元素的幾何尺寸沒有變。
為什么通常推薦將 CSS <link> 放置在 <head></head> 之間,而將 JS <script> 放置在 </body> 之前?你知道有哪些例外嗎?
如果將 js 放在 head 里面,則會先被瀏覽器解析,但是這時的 body 還沒被解析,如果這個時候,瀏覽器解析到 js 出現(xiàn)錯誤,就會阻止后續(xù)的渲染。
例外的話?
一般都會綁定一個監(jiān)聽 onload,當(dāng)全部的html文檔解析完之后,再執(zhí)行代碼
window.onload = function() {
// 將所有 js 代碼都在 window.onload 方法加載
}
什么屬性能讓瀏覽器直接使用ES6 Module
<script type="module">
import {addTextToBody} from './utils.js';
addTextToBody('Modules are pretty cool.');
</script>


