javascript dom编程艺术读书笔记之图片库改进版
1.javascript和HTML是分离的吗
该示例支持平稳退化
目前他们还是混合在一起,我们要找到一种挂钩把他们关联起来。
我们可以为ui设置一个ID
<ul id=""imagegallery">
2.添加事件处理函数
编写一个简单的函数把有关操作关联到onload上,命名为prepareGallery
- 检查浏览器是否理解getElementByTagName
- 检查浏览器是否理解getElementById
- 检查网页是否存在一个imagegallery的元素
- 遍历该元素所有链接
- 设置onload事件,点击链接完成以下操作
把这个连接作为参数传递给showPic函数
取消链接的默认行为
a. 检查点
if (!getElementById || !getElementByTagName) return false;
可以进行更针对性的写法,将函数处理链接设置为imagegallery链接。这是预防性措施,即使从网页上删除图片库也不用担心出错。不应该让javascript对网页有依赖。
if(!document.getElementById("imagegallery"){
return false;
}
出于可读性考虑,我们将测试集中开头
fuction prepareGallery(){
if (!document.getElementByTagName) return false;
if (!document.getElementById) return false;
if (!document.getElementById("imagegallery")) return false;
}
b. 变量名有什么
用gallery变量简化
var gallery=document.getElementById("imagegallery");
将数组赋值给变量links
var links=gallery.getElementByTagName("a");
prepareGallery函数目前的样子
fuction prepareGallery(){
if (!document.getElementByTagName) return false;
if (!document.getElementById) return false;
if (!document.getElementById("imagegallery")) return false;
var gallery=document.getElementById("imagegallery");
var links=gallery.getElementByTagName("a");
}
c. 遍历
for循环遍历
for ( var i=0; i<links.length; i++){}
d. 改变行为
links[i].onclick = function(){
showPic(this);
return false;
}
d. 完成javascript函数
fuction prepareGallery(){
if (!document.getElementByTagName) return false;
if (!document.getElementById) return false;
if (!document.getElementById("imagegallery")) return false;
var gallery=document.getElementById("imagegallery");
var links=gallery.getElementByTagName("a");
for ( var i=0; i<links.length; i++){
links[i].onclick = function(){
showPic(this);
return false;
}
}
}
3.共享onload事件
若在文档加载之前执行脚本,DOM不完整,测试的准确性无从谈起。因此在网页加载完毕后立即执行,我们把事件与onload关联起来
window.onload= prepareGallery;
如果有两个函数,firstFunction和secondFunction。逐一绑定,只有最后一个函数会被执行,可以创建一个匿名函数解决这个问题
window.onload = function(){
fistFunction();
secondFunction();
}
还有一种弹性最佳解决方案
用addLoadEvent函数
function addLoadEvent(func){
var oldonload = window.onload;
if (typeof window.onload != 'function'){
window.onload = func;
}
else{
window.onload = function(){
oldonload();
func();
}
}
}
将页面加载执行的函数创建一个队列。把函数添加队列中
addLoadEvent(fistFunction);
addLoadEvent(secondFunction);
4.不要做太多假设
在之前showPic函数中,没有进行任何检测。
showPic函数有prepareGallery调用,在prepareGallery中已经检测了getElementById和getElementByTagName。在showPic中并没有检查placeholder和description函数。
进行操作只有placeholder图片存在,即使description不存在也可以替换图片。
下面是showPic添加检查之后的代码
functions showPic (whichpic){
if (document.getElementById("placeholder") return false;
var source = getAttribute("href");
var placeholder = document.getElementById("placeholder")l
placeholder.setAttribute("src", source);
if (document.getElementById("description")){
var text = getAttribute("title");
var description = document.getElementById("description");
description.firstChild.nodeValue = text;
}
return true;
}
现在即使没有placeholder图片也不会出现任何问题,有一个问题,如果把placeholder图片从标记文档中删除,无论我们点击图片库里哪个链接都不会有反应
意味脚本不支持平稳退化。
问题在于prepareGallery假设,showPic函数正常返回,取消了onclick的默认行为,应该有showPic函数决定
我们应该验证showPic返回值
links[i].onclick = function(){
return !showPic(this);
}
showPic返回true,那我们就返回false,浏览器不会打开那个链接
showPic返回false,那我们就返回true,认为图片没有更新,打开链接
5.优化
showPic函数中仍然有需要处理的假设,title属性值
if whichpic.getAtteibute("title"){
var text = whichpic.getAttribute("title");
}else {
var text = "";
}
用三元操作符处理
var text = whichpic.getAttribute("title") ? whichpic.getAttribute("title") : "";
检测placeholder存在,假设是一张图片,可以用nodeName属性进行测试
注意nodeName属性总是返回一个大写字母值
if (placeholder.nodeName != "IMG") return false;
下面是加了几项检查后的showpic函数
functions showPic (whichpic){
if (document.getElementById("placeholder") return false;
var source = getAttribute("href");
var placeholder = document.getElementById("placeholder")l
if (placeholder.nodeName != "IMG") return false;
placeholder.setAttribute("src", source);
if (document.getElementById("description")){
var text = whichpic.getAttribute("title") ? whichpic.getAttribute("title") : "";
var description = document.getElementById("description");
if (description.firstChild.nodeType == 3){
description.firstChild.nodeValue = text;
}
}
return true;
}
6.键盘访问
按回车键触发点击,会触发onkeypress事件,与onclick行为是一样的
- 可以直接复制一份
links[i].onclick = function(){
return showPic(this) ? false : true;
}
links[i].onkeypress = function(){
return showPic(this) ? false : true;
}
- 把onclick赋值给onkeypress
links[i].onkeypress = links[i].onclick;
小心onkeypress
在几乎所有的浏览器中,用tab键移动,回车键点击也会触发onclick
onclick和onkeypress结合会导致很多问题
下面是最终的shoePic函数和prepareGallery函数
fuction prepareGallery(){
if (!document.getElementByTagName) return false;
if (!document.getElementById) return false;
if (!document.getElementById("imagegallery")) return false;
var gallery=document.getElementById("imagegallery");
var links=gallery.getElementByTagName("a");
for ( var i=0; i<links.length; i++){
links[i].onclick = function(){
return showPic(this) ? false : true;
}
}
}
functions showPic (whichpic){
if (document.getElementById("placeholder") return false;
var source = getAttribute("href");
var placeholder = document.getElementById("placeholder")l
if (placeholder.nodeName != "IMG") return false;
placeholder.setAttribute("src", source);
if (document.getElementById("description")){
var text = whichpic.getAttribute("title") ? whichpic.getAttribute("title") : "";
var description = document.getElementById("description");
if (description.firstChild.nodeType == 3){
description.firstChild.nodeValue = text;
}
}
return true;
}
7.把javascript和css结合起来
把图片链接换成缩略图css也同样有效
8.DOM Core和HTML-DOM
var source = whichpic.getAttribute("href");
var source = which.href;
placeholder.setAttribute("src", source);
placeholder.src = source;
第一行为DOM Core
第二行为HTML-DOM