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

posted @ 2017-09-21 10:22  阿浩yohann  阅读(151)  评论(0编辑  收藏  举报