1. 程式人生 > >《HTML5揭祕》讀書筆記整理(上)

《HTML5揭祕》讀書筆記整理(上)

《HTML5揭祕》並不是一本工具手冊,而是一本可以教會你如何使用HTML5的書

這篇文章整理前5章,後5章見讀書筆記(下)轉載請標明出處

《HTML5揭祕》讀書筆記整理(上)

《HTML5揭祕》

第1章 從開始到現在

每當web瀏覽器請求一個頁面時,伺服器會在傳送實際頁面之前先發送一些頭資訊(header),頭資訊通常不可見。

最重要的頭資訊是 Content-Type

,比如:
Content-Type:text/html

text/html”就是這個頁面的“內容型別”,或者稱為“MIME型別”,這個頭資訊將唯一確定某個資源本質是什麼,因而決定其如何被呈現。

JPEG圖片的MIME型別:image/jpeg(本質是什麼/如何被呈現)
PNG圖片的MIME型別:image/png(本質是什麼/如何被呈現)

綜述:凡是可以用一個URL地址定位的東西,比如HTML,圖片,指令碼,視訊,PDF等等都具有特定的MIME型別。

第2章 HTML5特性檢測

HTML5只是一些獨立特性的集合,因此你不能檢測瀏覽器是否支援“HTML5”,這樣毫無意義,但可以分別檢測瀏覽器是否支援諸如“畫布(canvas)”、“視訊(video)”、“地理位置(geolocation)”等HTML5特性。

瀏覽器渲染web頁面會構造DOM,用一個物件集來表示頁面上的HTML元素。
所有的DOM物件共享一些公共屬性,但有些物件會擁有特定屬性,從這些特性DOM中尋找特性屬性即檢測哪些HTML5特性被支援。

四種檢測HTML5特性方法

四種基本技術檢測是否支援某種HTML5特性,從簡到複雜為:

  1. 檢測全域性物件(諸如window或者navigator)是否擁有特定屬性,以檢測地理位置為例。
  2. 建立一個元素,檢測該元素的DOM物件是否擁有特定屬性,以檢測畫布特性為例。
  3. 建立一個元素,檢測該元素的DOM物件是否擁有特定方法,同時呼叫這個方法並檢查它返回值,以檢測支援視訊格式為例。
  4. 建立一個元素,給這個元素的DOM物件設定特定的屬性值,然後檢查瀏覽器是否保留了該屬性,以檢測支援的型別為例。

Modernizr:一個HTML5特性檢測庫。
Modernizr是自動執行的,執行時會建立一個對應的布林型別的屬性,例如:如果你支援畫布,則Modernizr.canvas的屬性值是true,反之為flase。

if(Modernizr.canvas){
//開始畫吧!
}else{
//瀏覽器不支援canvas
}

一些HTML5特性的檢測

畫布(Canvas)

方法2:如果瀏覽器支援canvas API,那麼建立元素對應的DOM物件會擁有getContext()這個方法。

function supports_canvas(){
	return !!document.createElement('canvas').getContext;
}

使用雙重否定來強制讓這個檢測方法返回一個布林值。

視訊(Video)

方法2:如果瀏覽器支援video,被建立的元素對應的DOM物件會有一個名為canPlayType()的方法。

function supports_video(){
	return !!document.createElement('video').canPlayType;
}

同樣可以呼叫Modernizr庫來檢測(Modernizr.video)。

視訊格式(Formats)

編寫視訊的語言被稱為:編碼演算法(codec)——將視訊編碼成位元流的演算法。編碼演算法的分歧已經縮到兩種:①Safari和iphone遵循的專利編碼演算法
②Chromium和Mozilla Firefox開源的編碼演算法
方法3:如果瀏覽器支援某種視訊格式,被建立的元素對應的DOM物件會有一個canPlayType()的方法,利用該方法可知道是否支援某種視訊格式。

function supports_h264_baseline_video(){
	if(!supports_video){return false;}
	var v = document.createElement('video');
	return v.canPlayType('video/mp4;codecs="avc1.42Eo1E,mp4a.40.2);
}
本地儲存(Local Storage)

cookie大小受限,每次請求新頁面,cookie資訊都會被髮送回伺服器,而HTML5本地儲存,在使用者計算機上,網站可以在頁面載入完畢後通過Javascript獲取。
方法1:如果瀏覽器支援本地儲存,全域性物件會有一個localStorage屬性,反之,window物件的該屬性值為undefined。

function supports_local_storage(){
	return ('localStorage' in window)&&window['localStorage'] !== null;
}
web Workers

提供了一種標準的方式讓瀏覽器能在後臺執行JavaScript,通過web Worker可以產生“多執行緒”,這些“後臺執行緒”可以在頁面響應使用者的滾屏、點選或輸入時同時做一些諸如複雜數學運算、傳送網路請求等事情。
方法1:全域性物件window會有一個Worker屬性,反之,該屬性為undefined。

function supports_web_workers(){
	return !!window.Worker;
}
離線web應用(Offline Web Applications)

一旦瀏覽器下載了第一次訪問的具有離線訪問功能的web站點時的必須檔案後,下次在沒有網路的情況下,瀏覽器會使用下載的離線檔案來訪問該頁面。
方法1:如果瀏覽器支援離線web應用,全域性物件window回擁有一個名為applicationCache的屬性,反之,該屬性為undefined。

function supports_offline(){
	return !!window.applicationCache;
}
地理位置(Geolocation)

定位的方法
①IP地址
②利用基站獲取手機無線網路的接入位置
③通過能利用衛星定位系統獲得經緯度資訊的GPS裝置。
方法1:如果瀏覽器支援地理位置API,全域性物件navigator會有一個geolocation屬性,反之,該屬性為undefined。

function supports_geolocation(){
	return !!navigator.geolocation;
}
輸入框型別(Input Types)

HTML5中定義了很多新輸入框(input)型別:

    <input type = "search">搜尋框</br></br>
	<input type = "number">數字型別輸入框</br></br>
	<input type = "range">範圍選擇滑塊</br></br>
	<input type = "color">顏色選擇器</br></br>
	<input type = "tel">電話號碼輸入框</br></br>
	<input type = "url">網址輸入框</br></br>
	<input type = "email">地址輸入框</br></br>
    <input type = "date">日期選擇器</br></br>
    <input type = "month">月份輸入框</br></br>
    <input type = "week">星期輸入框</br></br>
    <input type = "time">時間戳輸入框</br></br>
    <input type = "datetime">精確日期/時間戳輸入框</br></br>
    <input type = "datetime-local">當地日期和輸入框</br></br>

在這裡插入圖片描述
方法4:建立一個虛擬的<input>元素,然後將input型別設定為要檢測的型別,如果瀏覽器支援特定的輸入框型別,那麼設定的type屬性會被保留,反之,瀏覽器會忽略設定的值,type屬性依然為預設的text。

var i = document.createElement("input");
i.setAttribute("type","color");
return i.type !== "text";
佔位文字(Placeholder Text)

當輸入框為空或失去焦點的時候顯示出來,一旦使用者點選輸入框(或者使用Tab鍵使其獲得焦點),佔位文字就會消失。
方法2:如果瀏覽器支援佔位文字,建立的<input>元素對應的DOM物件會有一個placeholder屬性,反之,該DOM物件沒有該屬性。

function supports_input_placeholder(){
var i = document.createElement('input');
return 'placeholder' in i;
}

第3章 從這一切的含義

文件型別(doctype)

!DOCTYPE html
PUBLIC “_//W3C//DTD XHTML 1.0 Strict//EN”
"http://www.w3.org/TR/xhtml1/DTD/xhtml-strict.dtd

HTML5的doctype

!DOCTYPE html

一個頁面的根元素始終是<html>元素
根元素的第一個元素通常是<head>元素,包含元資料——關於網頁本身的資訊,而不是網頁主體。

朋友和(連結)關係

連結關係(link relationship)提供一種解釋為什麼連結到那個頁面。
兩種類別的連結可以由link元素建立,外部資源連結引入那些用於加強當前文件的資源,超連結則指向其他文件。
①rel = "stylesheet"
②rel = “alternate”(該type屬性值是Rss或者Atom等媒介型別,由此開啟“聚合內容自動發現機制”)
③rel = “archives” 表示所引用文件描述了一組收藏,包括記錄,文件或者有價值的材料
④rel = “author” 表示連結到該頁面作者的相關資訊
⑤rel = “external” 表示該連結指向一個和當前文件不同的,並不屬於站點一部分的文件(訪客留言中所含有的連結加上這個屬性)
⑥rel = “start”,rel = “prev”,rel = “next” 表示一篇文章或部落格的不同位置章節
⑦rel = “icon” ,通常和shortcut一起使用,它們將頁面與一個小圖示相關聯,通常這個小圖示會顯示在位址列的網址旁邊,或者瀏覽器的標籤卡上,或者兩處都顯示。

瀏覽器如何處理未知元素

如果IE不識別一個元素,它就會在DOM中插入一個沒有子節點的空節點,所有原本定義在其內的子元素,將全部轉為它的兄弟元素,為此在使用IE不認識的標籤之前,先用Js建立一個虛假的該元素,它並沒有真正插入到DOM中,就可以為其設定樣式了。
實現如下:

<!--[if It IE 9]>
<script>
	var e = ("abbr,article,aside,audio,canvas,details,figure,footer,header,hgroup,"+
	   "mark,menu,meter,nav,output,progress,section,time,video").split(',');
	for (var i = 0;i<e.length;i++){
		document.createElement(e[i]);
	}
</script>
<![endif]-->

HTML5語義元素

頁頭(Headers)

問題引發?HTML4並沒有提供方法來標註副標題,它們無法避免地會被加入到文件大綱裡。
解決方法:使用hgroup將兩相關倆標題打包

<header>
	<hgroup>
		<h1>My weblog</h1>
		<h2>A lot of balabala...</h2>
	</hgroup>
</header>
文章(Articles)

每個<article>中都可包含<h1>元素,這並不構成問題,所有東西都位於一個<article>容器內,該<article>元素定義了一個自包含的頁面大綱節點,<h1>元素給這個節點提供了標題,頁面上已有的章節元素也會保持其原有巢狀層級。

日期(Dates and Times)

HTML5中<time>元素由三部分組成:

  • 一個機器可識別的時間戳
  • 人可識別的文字內容
  • 一個可選的pubdate標記

如果還想包含時間,在日期後面加上T,然後跟24消逝以及時區偏移量

<time datetime = "2018-11-13T10:48:10-04:00" pubdate>November 13,2018 10:48am
</time>

pubdate是一個布林屬性,需要寫上即可,意義是如果該<time>位於一個<article>裡,它表示該時間戳是文章發表的時間,如果不在<article>裡,表示為整個文件釋出時間。

導航(Navigation)

導航語義性考慮情況:
①殘障人士
②盲人(閱讀器)

第4章 Canvas繪圖

HTML5中定義<canvas>元素為:“它是依賴解析度的點陣圖畫布,可以在canvas上繪製任意圖形,甚至載入圖片”。

canvas是一塊布,它什麼都沒有,需要用javascript來繪製圖形。

建立一個canvas,並給它一個id

<canvas id = "a" width = "300" height = "225"></canvas>

建立canvas後就有了繪圖上下文(包含了所有繪製方法和屬性的定義),我們呼叫它的getContext()方法,並傳遞一個“2d”引數給它。

畫個矩形吧:

function draw_b(){
	var b_canvas = document.getElementById("a");
	var context = b_canvas.getContext("2d");
	context.fillRect(50,25,150,100);
	context.strokeRect(50,150,150,100);
}

在這裡插入圖片描述
fillstyle可以設定css顏色、一個圖案或種顏色漸變,fillstyle預設是純黑色。
fillRect(x,y,width,height)(實心填充)
strokeRect(x,y,width,height) (描邊繪製)
clearRect(x,y,width,height)(清除指定矩形區畫素)

canvas小案例:網格座標軸

window.onload = function startCanvas(){
	var d_canvas = document.getElementById("d");
	var context = d_canvas.getContext("2d");
	for(var x=0.5;x<500;x+=10){
		context.moveTo(x,0);
		context.lineTo(x,375);
	}
	for(var y=0.5;y<375;y+=10){
		context.moveTo(0,y);
		context.lineTo(500,y);
	}
	context.strokeStyle = "#eee";
	context.stroke();

    context.beginPath();
    context.moveTo(0,40);
    context.lineTo(240,40);
    context.moveTo(260,40);
    context.lineTo(500,40);
    context.moveTo(495,35);
    context.lineTo(500,40);
    context.lineTo(495,45);
    context.moveTo(60,0);
    context.lineTo(60,153);
    context.moveTo(60,173);
    context.lineTo(60,375);
    context.moveTo(65,370);
    context.lineTo(60,375);
    context.lineTo(55,370);
    context.strokeStyle = "#000";
    context.stroke();
    context.font = "bold 12px sans-serif";
    context.fillText("x",248,43);
    context.fillText("y",58,165);
    context.textBaseline = "top";
    context.fillText("(0,0)",8,5);
    context.textAlign = "right";
    context.textBaseline = "bottom";
    context.fillText("(500,375)",492,370);
    context.fillRect(0,0,3,3);
    context.fillRect(497,372,3,3)
}

在這裡插入圖片描述

備註:

  • moveTo(x,y)把鉛筆移到指定點並作為線條開始點
  • lineTo(x,y)繪製線條到指定的結束點

這些都是“鉛筆”方法,其實並沒有真正花到canvas上,還需要一個“畫筆”方法,把圖案繪製到canvas上去:

context.strokestyle = "#eee";
context.stroke();

文字(Text)

canvas文字:沒有浮動,沒有邊距,沒有留白,也沒有自動換行。
繪製上下文有一些字型屬性:

  • font包括字型樣式、字型變種(font variant)、字型大小、字型粗細、行高和名稱
  • textAlign控制文字對齊方式,它類似於css中的text-align。可能的取值有start、end、left、right和center
  • textBaseline控制文字相對於起點的位置。可能有top、hanging、middle、alphabetic和bottom

對於簡單的英文字母:放心使用top,middle和bottom作為文字基線

顏色漸變(Gradients)

  • createLinearGradient(x0,y0,x1,y1) 沿著(x0,y0)至(x1,y1)繪製漸變
  • createRadialGradient(x0,y0,r0,x1,y1,r1) 沿著兩個圓之間的錐面繪製漸變。前三個引數代表開始的圓,圓心為(x0,y0),半徑為r0。最後三個引數表示結束的圓,圓心為(x1,y1),半徑為r1.

圖片(Images)

canvas繪圖上下文定義了幾種繪製圖片的方法:

  • drawImage(image,dx,dy) dx,dy代表圖片左上角
  • drawImage(image,dx,dy,dw,dh) 將其縮放為寬dw,高dh位置
  • drawImage(image,sx,sy,sw,sh,dx,dy,dw,dh) 通過引數(sx,sy,sw,sh)指定裁剪後縮放再放到dx,dy
    在這裡插入圖片描述

第5章 視訊

視訊檔案通常包含多個軌道:一個視訊軌(無音訊),加上一個或多個音訊軌(無視訊),軌道互聯,音軌包含一些標記,輔助音訊同步。

流行視訊容器格式
MPEG-4、Flash、ogg、webM,音視訊交錯。

視訊編解碼器

實際上就是一個演算法,當想要觀看一個視訊時,播放器會做以下工作:

  1. 解析容器格式以找出可使用的視訊和音訊軌道,並分析其儲存結構
  2. 對視訊流解碼,並在螢幕上顯示一幅幅影象
  3. 對音訊流解碼,同時給揚聲器傳輸聲音訊號

H.264為MPEG-4高階視訊編碼

音訊編解碼器

實際上也是一個演算法,同視訊一樣,包括有損和無損兩種。
音訊流解碼:對音訊流解碼並轉換為電子波形,揚聲器將電子波形轉換為聲音,大部分通用音訊播放器解碼器可以處理兩個聲道。
MP3歌曲可以最多包含兩個聲道,它們可以解碼為不同的位元率:64kps、128kps以及192kps等中間一種

高階音訊編碼AAC由蘋果製造,目的是在相同位元率下提供比MP3更好的音質,它可以按任意位元率編碼

視訊相容

為了獲得最大相容性,處理視訊流程大概是:

  • 製作一個ogg容器中使用Theora視訊和Vorbis音訊版本
  • 製作另外一個版本,使用webM視訊容器 (VP8+Vorbis)
  • 再製作一個版本,使用MP4視訊容器,並使用H2.64基本和AAC低配音訊
  • 連結3個檔案到同一<video>元素,並向後相容基於flash的視訊容器