《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特性,從簡到複雜為:
- 檢測全域性物件(諸如window或者navigator)是否擁有特定屬性,以檢測地理位置為例。
- 建立一個元素,檢測該元素的DOM物件是否擁有特定屬性,以檢測畫布特性為例。
- 建立一個元素,檢測該元素的DOM物件是否擁有特定方法,同時呼叫這個方法並檢查它返回值,以檢測支援視訊格式為例。
- 建立一個元素,給這個元素的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,音視訊交錯。
視訊編解碼器
實際上就是一個演算法,當想要觀看一個視訊時,播放器會做以下工作:
- 解析容器格式以找出可使用的視訊和音訊軌道,並分析其儲存結構
- 對視訊流解碼,並在螢幕上顯示一幅幅影象
- 對音訊流解碼,同時給揚聲器傳輸聲音訊號
H.264為MPEG-4高階視訊編碼
音訊編解碼器
實際上也是一個演算法,同視訊一樣,包括有損和無損兩種。
音訊流解碼:對音訊流解碼並轉換為電子波形,揚聲器將電子波形轉換為聲音,大部分通用音訊播放器解碼器可以處理兩個聲道。
MP3歌曲可以最多包含兩個聲道,它們可以解碼為不同的位元率:64kps、128kps以及192kps等中間一種
高階音訊編碼AAC由蘋果製造,目的是在相同位元率下提供比MP3更好的音質,它可以按任意位元率編碼
視訊相容
為了獲得最大相容性,處理視訊流程大概是:
- 製作一個ogg容器中使用Theora視訊和Vorbis音訊版本
- 製作另外一個版本,使用webM視訊容器 (VP8+Vorbis)
- 再製作一個版本,使用MP4視訊容器,並使用H2.64基本和AAC低配音訊
- 連結3個檔案到同一
<video>
元素,並向後相容基於flash的視訊容器