前兩章的基礎內容自己之前的JavaScript筆記已記錄過,就不再贅述,直接從第三章Dom開始,Dom內容之前也有寫筆記,這里算是補充。
- <a href="#c1">第三章 Dom</a>
- <a href="#c2">第四章 案例:JavaScript圖片庫</a>
- <a href="#c22">第五章 最佳實踐</a>
- <a href="#c222">第六章 JS圖片庫改進版</a>
第一章 JavaScript簡史
第二章 JavaScript語法
<a name="c1"></a>第三章 Dom
- Document Object Model,文本對象模型
- 一篇文檔就是一顆節點樹
- 常用的三種節點:文本節點、元素節點、屬性節點
- Dom中三種方式獲得元素節點:
- getElementById 返回一個與有特定ID值的元素節點對應的對象
- getElementByTagName 返回一個對象數組(更準確地說,是一個節點列表),可把通配符(*)作為其參數
- getElemetnByClassName 返回一個對象數組(更準確地說,是一個節點列表),需要考慮解決兼容性:
function getElementsByClassName(node,classname) {
if(node.getElementsByClassName) {//使用現有方法
return node.getElementByClassName(classname);
}else{
var results = new Array();
var eles = node.getElementsByTagName("*");
for(var i = 0;i<elems.length;i++) {
if(elems[i].className.indexOf(classname)!=-1){
results[results.length] = elems[i];
}
}
return false;
}
}
- 獲取和設置屬性
getAttribute,setAttribute,只能用于元素節點
object.setAttribute(attribute, value);
,創建屬性,并賦值,這個很常用。
for(var i = 0; i<paras.length;i++) {
var title_text = paras[i].getAttribute("title");
if (title_text) {
paras[i].setAttribute("title","brand new title text");
alert(paras[i].getAttribute("title"));
}
<a name = "c2"></a>第四章 JS圖片庫
function showPic(whichpic){
var source = whichpic.getAttribute("href");
var placeholder = document.getElementById("placeholder");
var text = whichpic.getAttribute("title");//某個圖片鏈接被點擊時,該鏈接的title屬性值將被提取并保存到變量text中
var description = document.getElementById("description");
placeholder.setAttribute("src", source);//source是屬性src的值
description.firstChild.nodeValue = text;//把description對象的第一個子節點的nodeValue屬性值設置為變量text的值
}
//上邊的注釋可作為編程的思路
- function showPic(whichpic)
whichpic代表一個元素節點,是一個指向某個圖片的<a>
元素需要分解出圖片的文件路徑,可通過在whichpic元素上調用getAttribute得到。 - onclick = "showPic(this); return false";
把onclick事件處理函數嵌入到一個鏈接中時,需要把這個鏈接本身用作該函數的參數,this表示“這個對象”/“這個<a>
元素節點”。
點擊鏈接時,showPic函數會被調用,但是鏈接點擊的默認行為也會被調用,阻止默認行為:onclick = "return false;"
當為return false
時,onclick事件處理函數則認為這個鏈接未被點擊。
<a name = "c22"></a>第五章 最佳實踐
- 平穩退化(graceful degradation):網頁在沒有JavaScript的情況下也能正常工作。
- JS中用
window.open(url,name,features)
打開新的瀏覽器窗口:
function popUp(winURL) {
window.open(winURL,"popup","width=320,height=480");
}
- 調用函數時"javascript: "偽協議和內嵌事件處理函數都不能實現平穩退化
"javascript: "偽協議:
<a href="javascript:popUp('http://www.example.com/');">Example</a>
內嵌事件處理函數:
<a href="#" onclick="popUp('http://www.example.com/'); return false;">Example</a>
- 解決辦法:
在鏈接里給href屬性設置真實存在的URL(依然存在不足之處:每次打開新窗口,都需要把JS代碼嵌入到標記文檔中)
<a onclick="popUp(this.href ); return false;">Example</a>
- 分離JavaScript
window.onload = prepareLinks;
function prepareLinks(){
//把事件添加到有著特定屬性的一組元素上
var links = document.getElementsByTagName("a"); //1.把文檔里的所有鏈接全放入一個數組里
for (var i=0; i<links.length; i++) {//2.遍歷數組
if (links[i].getAttribute("class") == "popup"){// 3.如果某個鏈接的class屬性等于popup,就表示這個鏈接在被點擊時應該調用popUp()函數
popUp(this.getAttribute("href")); //1)把這個鏈接的href屬性值傳遞給popUp()函數
return false; //2)取消這個鏈接的默認行為
}
}
}
function popUp(winURL){
window.open(winURL,"popup","width=320,height=480");
}
//注釋可作為編程思路
- 把事件添加到有著特定屬性的一組元素上,步驟:
- 把文檔里的所有鏈接全放入一個數組里;
- 遍歷數組;
- 如果某個鏈接的class屬性等于popup,就表示這個鏈接在被點擊時應該調用popUp()函數:
- 把這個鏈接的href屬性值傳遞給popUp()函數
- 取消這個鏈接的默認行為
- window.onload = function{...}
把代碼打包到函數prepareLinks里,并添加到window對象觸發的onload事件上。必須的步驟,不然加載腳本時文檔可能不完整,導致模型、DOM都不完整,代碼無法正常工作
- 向后兼容,對象檢測
if (!getElementyById || !getElementsByTagName) return false;
//一定要刪掉方法后的圓括號,如果不刪掉,測試的將是方法的結果,無論方法是否存在。
- 性能考慮
- 盡量少訪問DOM和減少標記
在多個函數都會去的一組類似元素的情況下,可以考慮重構代碼,把搜索結果保存在一個全局變量里,或者把一組元素直接以參數形式傳遞給函數 - 合并和放置腳本
包含腳本的最佳方式是使用外部腳本,因為外部文件與標記能清晰的分離開,把多個腳本合并到一個中,減少請求。減少請求數量通常是性能優化首先要考慮的。
把所有<script>
標簽都放到文檔末尾,</body>
標簽之前 - 壓縮腳本
把腳本中不必要的字節,如空格和注釋,統統刪除(查看網頁源碼時便能體驗到)
常用的代碼壓縮工具:
JSMin
YUI Compressor
Closure Compiler
<a name="c222"></a> 第六章 JS圖片庫改進版
1.JavaScript與HTML標記分離
開始時onclick事件處理函數直接插入到HTML文檔里:
<ul>
<li><a href = "#" onclick = "showPic(this); return false;" title = "..."></li>
...
</ul>
為<ul>
設置id屬性便可把JS移出文檔:
<ul id = "imagegallery">...
- 添加事件處理函數,該函數完成以下工作:
- 檢查當前瀏覽器是否理解getElementByTagName;
- 檢查當前瀏覽器是否理解getElementById;
- 檢查當前網頁是否存在一個id為imagegallery的元素;
- 遍歷imagegallery元素的所有鏈接
- 設置onclick事件,讓它在有關鏈接被點擊時完成以下操作:
1)把這個鏈接作為參數傳遞給showPic函數;
2)取消鏈接被點擊時的默認行為。
function prepareGallery() {
if (!document.getElementsByTagName) return false;
if (!document.getElementById) return false;
if (!document.getElementById("imagegallery")) return false;//1.檢查點
var gallery = document.getElementById("imagegallery");
var links = gallery.getElementsByTagName("a");//2.變量
for ( var i=0; i < links.length; i++) {//3.遍歷
links[i].onclick = function() {//4.改變行為
// return !showPic(this);
retrun showPic(this) ? false : true;//this在這里代表links[i]
}
//links[i].onkeypress = links[i].onclick;盡量不使用鍵盤觸發事件
}
}
---
links[i].onclick = function() 定義了一個匿名函數:一種在代碼執行時創建函數的辦法。這個匿名函數里的所有語句都將在link[i]元素被點擊時執行。
return !showPic(this):
1.如果showPic返回true,我們就返回false,瀏覽器不會打開那個鏈接;
2.如果showPic返回false,我們認為圖片沒有更新,于是返回true以允許默認行為發生
3.this在這里代表links[i]
- 共享onload事件
把創建的函數綁定到事件上:window.onload = prepareGallery;
如果有多個函數想在頁面加載完畢時立即執行,可以創建如下函數:
window.onload = function(){
fisrtFunction();
secondFunction();
...
}
更好的解決方案是利用函數addLoadEvent,它只有一個參數:打算在頁面加載完畢時執行的函數的名字,如下:
//代碼的注釋部分即為addLoadEvent函數將要完成的操作
function addLoadEvent(func) {//只有一個參數,在頁面加載完畢時執行的函數的名字
var oldonload = window.onload;//把現有的window.onload事件處理函數的值存入變量oldonload
if (typeof window.onload != 'function') {
window.onload = func;//如果這個處理函數上還沒有綁定任何函數,把新函數添加給它
} else {
window.onload = function() {
oldonload();
func();//如果這個處理函數上已經綁定了一些函數,就把新函數追加到現有指令的末尾
}
}
}
addLoadEvent(prepareGallery);
2.DOM Core和HTML-DOM
getElementById
,getElementsByTagName
,setAttribute
,getAttribute
等方法都是DOM Core的組成部分,不專屬于JavaScript,支持DOM的任何一種語言都可以使用。
關于HTML-DOM可以參考這里。