這是《JavaScript學(xué)徒》系列的第十課畏铆,今天會進(jìn)入《JavaScript DOM 編程藝術(shù)》第6章瓶逃,將上一章的最佳實踐應(yīng)用到圖片庫例子中。
本文同步發(fā)表于我的個人網(wǎng)站:
《JavaScript DOM 編程藝術(shù)》10:應(yīng)用最佳實踐 - 程式學(xué)徒 ZackLive?zacklive.com
教學(xué)視頻連結(jié)
能否平穏退化揭蜒?
以這段程式為例秘遏,href中我們不使用JavaScript偽協(xié)議(javascript:)或者#號儡司,就是為了即使JavaScript不可用,程式仍能打開圖片渐尿。
JavaScript是否與HTML標(biāo)記分離醉途?
在上面那段程式中,onclick的部分便是JavaScript砖茸,它跟HTML混在一起了隘擎。這是可以改進(jìn)的地方。
首先凉夯,將onclick從各連結(jié)移除货葬,并為ul加入id = imagegallery。再加入以下函數(shù):
function prepareGallery() {? if (!document.getElementsByTagName ||? ? ? !document.getElementById ||? ? ? !document.getElementById("imagegallery")) return false;? var gallery = document.getElementById("imagegallery");? var links = gallery.getElementsByTagName("a");? for ( var i=0; i
這個函數(shù)先檢查我們要用的方法劲够,再透過剛加入的id取得圖片庫中所有連結(jié)震桶,最后為每一條連結(jié)綁定onclick事件,并賦與它一個函數(shù)來執(zhí)行showPic及返回false征绎。
prepareGallery函數(shù)要在網(wǎng)頁載入后馬上執(zhí)行蹲姐,可以使用之前提到的window.onload,但我們可能有多個需要在載入后馬上執(zhí)行的函數(shù)炒瘸,因此淤堵,我們需要以下函數(shù):
function addLoadEvent(func) {? var oldonload = window.onload;? if (typeof window.onload != 'function') {? ? window.onload = func;? } else {? ? window.onload = function() {? ? ? oldonload();? ? ? func();? ? }? }}
這個函數(shù)先將舊的window.onload存到一個變量oldonload中,接著判斷舊window.onload是否已經(jīng)是函數(shù)顷扩,如果不是拐邪,代表里面沒有任何函數(shù),可以將新函數(shù)func直接賦與隘截;如果是扎阶,則代表里面存在其他函數(shù),那就將舊函數(shù)oldonload和新函數(shù)func一起放到一個新的函數(shù)里再賦與window.onload婶芭。
我們可以重復(fù)使用這個函數(shù)东臀,將多個函數(shù)放入window.onload:
addLoadEvent(prepareGallery);
至此,我們成功將JavaScript和HTML分離犀农。
最后惰赋,我們也應(yīng)為showPic函數(shù)加上檢查:
function showPic(whichpic) {? if (!document.getElementById("placeholder")) return false;? var source = whichpic.getAttribute("href");? var placeholder = document.getElementById("placeholder");? placeholder.setAttribute("src", source);? var text = whichpic.getAttribute("title");? if (description = document.getElementById("description")) description.firstChild.nodeValue = text;? return true;}
在第二個if的條件當(dāng)中,我直接進(jìn)行賦值,這是因為對if來講赁濒,賦值的結(jié)果正是被賦值的值轨奄。
至于最后為什么要返回true,這是要告訴prepareGallery拒炎,showPic沒發(fā)生任何錯誤挪拟。前面的prepareGallery,不管showPic是否成功都會返回false击你,也就是取消連結(jié)的跳轉(zhuǎn)動作玉组。這樣,萬一showPic出錯丁侄,連結(jié)就會失效惯雳,不能平穩(wěn)退化。因此绒障,onclick的函數(shù)應(yīng)改為:
return !showPic(this);
這代表showPic成功(showPic返回true)吨凑,我們應(yīng)取消連結(jié)跳轉(zhuǎn),即prepareGallery要返回false户辱,與showPic相反鸵钝;反之,若showPic出錯并返回false庐镐,prepareGallery則應(yīng)返回true恩商,讓連結(jié)進(jìn)行跳轉(zhuǎn)。
三元操作符(ternary operator)
showPic當(dāng)中還可以加入更多的檢查:
var text = whichpic.getAttribute("title") ? whichpic.getAttribute("title") : "";
這里的問號和冒號組成三元操作符必逆,意思是怠堪,若問號前的條件成立,取冒號前的值名眉;若不成立粟矿,則取冒號后的值。這里便是损拢,若存在title屬性陌粹,則取該屬性為text的值;若不存在福压,則取空字符串為text的值掏秩。
檢查placeholder是否為圖片:
if (placeholder.nodeName != "IMG") return false;
nodeName屬性永遠(yuǎn)是大寫字母。
這此檢查可按個人喜好加入荆姆。
鍵盤事件
按下鍵盤上任一個出鍵都會觸發(fā)onkeypress事件蒙幻,如果我們也想讓用戶按下鍵盤任意鍵來顯示圖片,可以加入:
links[i].onclick = function() {? return !showPic(this);}links[i].onkeypress = links[i].onclick;
但onkeypress會使所有鍵失去原本的功能胆筒,如Tab鍵邮破,不再能夠跳到下一個元素;同時,onclick其實也會被回車鍵觸發(fā)决乎,因此队询,如非必要派桩,不應(yīng)使用onkeypress构诚。
加入CSS
在index.html的head中加入:
<link rel="stylesheet" href="style.css">
接著新增style.css,并加入:
body {? color: #333;? background-color: #ccc;? margin: 1em 10%;}h1 {? color: #333;? background-color: transparent;}a {? color: #c60;? background-color: transparent;? font-weight: bold;? text-decoration: none;}ul {? padding: 0;}li {? float: left;? padding: 1em;? list-style: none;}#imagegallery {? list-style: none;}#imagegallery li {? display: inline;}#imagegallery li a img {? border: 0;}
DOM Core和HTML-DOM
DOM Core:任何程式語言都可以使用铆惑,不限JavaScript或網(wǎng)頁范嘱,方法包括
getElementById
getElementsByTagName
getAttribute
setAttribute
HTML-DOM:只適用于web文檔,較簡短:
DOM Core寫法:
element.getAttribute("src")placeholder.setAttribute("src", source);
HTMl-DOM寫法:
element.srcplaceholder.src = source
建議使用DOM Core方法员魏,JavaScript目前已不只用于網(wǎng)頁范籌丑蛤,習(xí)慣同一種寫法比較有利。