chapter 2: JavaScript 語法
JavaScript嵌入到html中的方式: 3種
JavaScript是弱類型動態語言,運行環境是瀏覽器,其中內置JavaScript引擎,熟知的像Chrome和NodeJS使用的V8引擎。
語法
語句: 像英語中的句子,只不過受體是瀏覽器
註釋: 受體是開發和維護的人.方式: //, /*...*/
變量: 計算機中的一小塊固定的內存區域,變量指向這塊內存的地址,內存代表的值就是變量的值.
程序運行過程中,變量的值可以改變.變量的名字區分大小寫.
數據類型: 弱類型語言,在聲明變量的時候可以不指定具體的數據類型,給予開發者更大的使用自由,但也容易出現運行時錯誤.
字符串: 單引號,雙引號是等價的.內容中的特殊字符可以轉義,'this is \'escaping\'.'
數值: 直接使用的是浮點數,整數只是其子集
布爾值: 只有兩個值true/false,對應電路的開與關,電流的有無
數組: 用一個變量表示值的集合.同一個數組中元素的類型可以不一致.
var ary = Array(12,'as',true);
對象: 對象也用一個名字表示一組值,對象的值都是其屬性,與數組不一樣的,屬性的名字可以是有意義的字符串.
var obj = {name:'obj',year:'1999',living:false };
操作
算術操作符: + - * /, ++, (),
拼接操作符: + 非數字
比較操作符:
邏輯操作符:
條件語句和循環語句
if
for/while
函數和對象
函數: 一組允許在代碼裏隨時調用的語句.每個函數都是一個短小的腳本
函數體對變量來說是局部作用域
對象: 是可以自定義的非常重要的數據類型.對象裏數據的訪問形式: 屬性和方法
內建對象: JavaScript自定義的對象 數組
宿主對象: 瀏覽器自定義的對象 document
用戶自定義對象:
chapter 3: DOM Document Object Model 文檔對象模型
- 一份文檔就是一棵節點樹
- 節點分爲不同的類型: 共12種,常用,元素節點1,屬性節點2,文本節點3,註釋節點8
- getElementId: 對應文檔裏的一個特定的元素節點
- getElementByTagName和getElementByclassName將返回一個對象數組,分別對應文檔裏的一組元素節點
- 每個節點都是一個對象
- 獲取屬性 node.getAttribute(“href”);
- 設置屬性 node.setAttribute(“src”, “test”);
chapter 4: JavaScript圖片庫
DOM提供的API編寫JavaScript腳本,使用事件處理函數將腳本與網友連接起來
事件處理函數: 特定的事件發生時調用特定的JavaScript代碼.被調用的JavaScript的函數會默認返回一個值,例如true.
如果我們要阻止瀏覽器執行默認操作,只要認爲寫入return false;
阻止用戶單擊圖片鏈接後跳轉界面
<a href="images/second.jpg" title='second' onclick="showPic(this);return false;"> second</a>
function showPic(e) {
let placeholder = document.getElementById("placeholder");
placeholder.setAttribute("src", e.getAttribute("href"));
if (!e.getAttribute("title")) return;
let imgdesc = document.getElementById("imgdesc");
imgdesc.firstChild.nodeValue = e.getAttribute("title");
}
DOM的屬性
childNodes 標準的,它返回指定元素的子元素集合,包括HTML節點,所有屬性,文本.
let bodyElement = document.getElementsByTagName("body")[0];
console.log(bodyElement.childNodes.length);
nodeType 判斷是哪種類型的節點
**1是元素節點,2是屬性節點,3是文本節點**
nodeValue
imgdesc.firstChild.nodeValue = e.getAttribute("title");
firstChild/lastChild
firstChild實際上是bodyElement.childNode[0]
chapter 5: 標記良好的內容就是一切
平穩退化: 用戶在瀏覽器不支持JavaScript的情況下仍能完成基本的操作.
<a href="http://www.baidu.com" onclick="popUp(this.href);return false;" title='Stationary degradation'>Stationary degradation</a>
JavaScript僞協議,不推薦
<a href="JavaScript:popUp('http://www.baidu.com')" title='fourth'> new tab</a>
分離JavaScript,參考CSS: 層疊樣式表 漸進增強原則
css: 將web文檔的內容結構(標記)和版面設計(樣式)分離開來
向後兼容
瀏覽器嗅探技術
性能考慮
儘量減少訪問DOM和儘量減少標記
每次訪問DOM標記都會搜索整個DOM樹
合併和放置腳本
script標籤放到</body>標籤之前可以讓頁面變得更快
壓縮文件
去掉空格,註釋等
chapter 6
原則: 行爲與表現分離
如果想用JavaScript給某個網頁添加一些行爲,就不應該讓JavaScript代碼對這個網頁的結構有任何依賴
儘量讓JavaScript代碼不依賴於沒有保證的假設,通過測試和檢查實現代碼的平穩退化
let placeholder = document.getElementById("placeholder");
if (!placeholder || placeholder.nodeName != "IMG") return false;
placeholder.setAttribute("src", e.getAttribute("href"));
沒有使用onkeypress事件處理函數,保證代碼的可訪問性
if (!links[i].onclick)
links[i].onclick = function () {
return !showPic(this);
};
// if (!links[i].onkeypress)
// links[i].onkeypress = links[i].onclick;
把事件處理函數從html標記文檔分離到外部的JavaScript文件,使JavaScript代碼不對這個網頁的結構有任何依賴
function prepareLinks() {
if (!document.getElementsByTagName) return false; //向後兼容
let links = document.getElementsByTagName('a');
for (let i = 0; i < links.length; i++)
if (links[i].getAttribute("class") == "popUp") {
links[i].onclick = function () {
popUp(this.getAttribute("href"));
return false;
}
}
}
DOM Core和HTML-DOM
[DOM Core](https://www.w3.org/TR/dom/): 定義了一個面向事件和樹結構的跨平臺模型.它規定了一套可以在瀏覽器,編譯器等平臺運行的樹結構的模型的API.
HTML-DOM: 用JavaScript實現的在瀏覽器中運行的DOM,爲了方便使用,簡寫一些API.
DOM Core HTML-DOM
element.getAttribute("src"); element.src;
chapter 7 動態創建標記
JavaScript通過創建新元素和修改現有元素來改變網頁結構
//在window.onload後面追加函數
function addloadEvent(func) {
let oldonLoad = window.onload;
if (typeof window.onload != 'function') {
window.onload = func
} else {
window.onload = function () {
oldonLoad();
func();
}
}
}
//在targetElement後邊插入newElement
function insertAfter(newElement, targetElement) {
let parent = targetElement.parentNode;
if (parent.lastChild == targetElement)
parent.appendChild(newElement);
else
parent.insertBefore(newElement, targetElement.nextSibling);
}
//圖片展示區域通過JavaScript代碼加載
function preparePlaceholder() {
if (!document.createElement || !document.createTextNode) return false;
if (!document.getElementById || !document.getElementById('imagallery')) return false;
// <img id="placeholder" src="images/first.jpg" alt="image gallery" height="" />
// <p id="imgdesc">choose an image.</p>
let placeholder = document.createElement('img');
placeholder.setAttribute("id", "placeholder");
placeholder.setAttribute("src", "images/first.jpg");
placeholder.setAttribute("alt", "image gallery");
let imgdesc = document.createElement("p");
imgdesc.setAttribute("id", "imgdesc");
let desc = document.createTextNode("choose an image.");
imgdesc.appendChild(desc);
let gallery = document.getElementById("imagallery");
insertAfter(placeholder, gallery);
insertAfter(desc, placeholder);
}
addloadEvent(preparePlaceholder);
Ajax 異步加載頁面內容的技術
Ajax可以只更新頁面中的一部分,優勢就是對頁面的請求以異步方式發送到服務器.
核心是XmlHttpRequest對象,充當着瀏覽器中腳本和服務器中間人的角色
chapter 8: 充實文檔的內容
- 不要用JavaScript添加內容到網頁上,因爲不支持JavaScript的用戶將看不到重要內容
漸進增強: 從最核心的部分開始,也就是從內容開始.應該根據內容使用標記實現良好的結構.
平穩退化: 漸進增強的實現必然支持平穩退化.按照漸進增強的原則去充實內容,那些缺乏css和dom支持的訪問者仍可以訪問到核心內容.
display屬性,inline: 橫向排列;block: 獨佔一行;none: 不顯示 - dom技術爲網頁添加的實用小功能,最終可以用另一種結構呈現核心內容
得到隱藏在屬性裏的信息
創建標記封裝這些信息
將標記插入到文檔中
基本思路: 用js函數先把文檔中的現有信息提煉出來,然後將信息以清晰有意義的方式重新插入到文檔中. - DOM方法
檢索信息: getElementById, getElementsByTagName, getAttribute
添加信息: createElement, createTextNode, appendChild, insertBefore, setAttribute
chapter 9: CSS-DOM
網頁:
結構層: HTML這類的標記語言創建,標籤描述網頁的語義
<p>this is text desc</p>
表示層: CSS來完成,描述頁面如何呈現
p { color: red;}
行爲層: JavaScript和DOM主宰的領域,負責如何響應事件
let paras = document.getElementsByTagName('p');
for(let i =0; i< paras.length;i++) paras[i].onclick = function(){alert("clicked.");}
style屬性
1. document.getElementById('id').style 這是一個對象
2. 獲取屬性:
color element.style.color
屬性中有連字符*-*的,JavaScript會解釋爲減號,所以要去掉並使用駝峯命名法
font-family element.style.fontFamily
3. style屬性只能返回內嵌樣式,就是緊跟在html標籤內部style中的樣式.
但是用DOM只能設置內嵌樣式,可以用style屬性獲取到
4. 設置樣式: document.getElementById('id').style.color = "black";
5. 使用場景:
1. 根據元素在DOM樹裏的位置設置樣式
let headers = document.getElementsByTagName("h1");
for (let i=0; i<headers.length; i++) {
let elem = getNextElement(headers[i].nextSibling);
elem.style.color = "red";
}
function getNextElement(node) {
if(node.nodeType == 1) {
return node;
}
if (node.nextSibling) {
return getNextElement(node.nextSibling);
}
return null;
}
2. 遍歷節點集合設置樣式, table標籤中設置奇偶行的樣式
let tab = document.getElementsByTagName('table')[0];
let rows = tab.getElementsByTagName('tr');
let odd = false;
for (let i =0; i< rows.length; i++){
if(odd == true){
rows[i].style.color = "orange";
odd = false;
}else{
odd = true;
}}
3. 事件發生時設置元素樣式
let rows = document.getElementsByTagName('tr');
for (let i=0;i<rows.length;i++){
rows[i].onmouseover = function(){this.style.fontWeight = "bold";}
rows[i].onmouseout = function(){this.style.fontWeight = "normal";}
}
classname屬性
與其用DOM直接改變某個元素的樣式,不如通過JavaScript更新元素的class屬性
odd { color: red; }
function addClass(ele, value){
if(!ele.className) { ele.className = value;}
else {ele.className = ele.className + " " + value; }
}
let tab = document.getElementsByTagName('table')[0];
let rows = tab.getElementsByTagName('tr');
let odd = false;
for (let i =0; i< rows.length; i++){
if(odd == true){
addClass(rows[i],"odd");
odd = false;
}else{
odd = true;
}}
chapter10 JavaScript實現動畫
動畫: 隨時間而改變某個元素在瀏覽器窗口裏的顯示位置
元素的位置 position, element.style.top
position: static 默認值,元素將按照在標記裏出現的先後順序出現在瀏覽器窗口
relative = static + float
absolute 絕對位置, 所處容器的絕對位置
top距離頂端 left距離左端 right bottom,對應的位置屬性最好只設置一個
element {
position: absolute;
top: 50px;
left: 100px;
}
setTimeout 設置函數經過一段時間後執行
let sample = setTimeout("function",interval);
clearTimeout(sample);
for(let i=0; i<5 ; i++){ setTimeout('alert(123)',2000*i); }
Note: 同時執行兩個movement()會產生變量爭用,,因爲js是單線程的,會導致死循環
解決: 介於全局變量和局部變量,作用於正在被移動的元素整個生命週期的的變量,元素的屬性
movement("message",300,400,100);movement("message",100,200,100);
movement = function (eleid, fx, fy, interval){
let ele = document.getElementById(eleid);
if(!ele) return false;
if(ele.move) clearTimeout(ele.move);
let px = parseInt(ele.style.left);
let py = parseInt( ele.style.top);
if(fx == px && fy ==py) return true;
console.log(px +","+ py);
if(fx>px) px++;
if(fx<px) px--;
if(fy>py) py++;
if(fy<py) py--;
ele.style.left = px + "px";
ele.style.top = py + "px";
let repeat = "movement('"+eleid+"',"+fx+","+fy+","+interval+")";console.log(repeat);
let ele.move = setTimeout(repeat,interval);
}
CSS overflow 處理元素尺寸超過容器尺寸的情況
1. visible 不裁剪溢出的圖片
2. hidden 隱藏溢出的內容,只顯示指定大小的圖片
3. scroll 類似於hidden,但會顯示一個滾動條
4. auto 類似於scroll,但只有內容溢出時纔會顯示滾動條
chapter11 HTML5
HTML5: 網頁三層的一個集合,提供了升級的技術並且向後兼容.
使用: 文檔聲明類型改爲**<!DOCTYPE html>**
[HTML5 技術](https://www.w3.org/TR/html/) ([中文](http://www.w3school.com.cn/html5/html_5_app_cache.asp))
1. 結構層 HTML : section,article,header,footer;canvas,audio,video
2. 樣式層 CSS : 高級選擇器,漸變,變換和動畫
3. 行爲層 DOM + javascrit API : 新元素有新的API;自定義video以改變其播放方式,form元素支持進度控制
canvas元素可以繪製圖形,添加圖片及其他對象
4. 新模塊 : Geolocation,Storage,Drap-and-Drop,Socket and web worker
canvas 圖片交互功能, JavaScript作爲畫筆的畫布
video & audio
不同的瀏覽器和視頻解碼算法是主要的阻礙,使用時注意向後兼容
<video id="video1" width="420" style="margin-top:15px;">
<source src="/example/html5/mov_bbb.mp4" />
<source src="/example/html5/mov_bbb.mp4" type="video/mp4" />
<source src="/example/html5/mov_bbb.ogg" type="video/ogg" />
Your browser does not support HTML5 video.
</video>
form
爲了應對不兼容的瀏覽器使用特性檢測準備另一個方案
Features and WebSites
webstorage
websocket
web workers
drag and drop
HTML Living Standard
W3C HTML5 Eorking Draft
Demos