内容简介
- 从文档中移除事件处理函数
- 向后兼容
- 确保可访问
6.2 平稳退化
<a href="./img/animals/1.jpg" onclick="showPic(this);return false;" title="Cat display">Cat</a>
禁用JavaScript的情况下,仍可访问图片。网页的基本功能完好。
若使用伪协议(“javascript:”),或将href设置为"#"网站基本功能将被损害。
6.3 JavaScript和HTML标记分离
即JavaScript是否作用于HTML之上还是混杂在一起?
混杂在一起:onclick事件处理函数直接插入到了标记文档中。
解决方法:
- 给标签a添加class处理比较麻烦。
- 好的解决方法是给整个清单设置一个单独的id。
<ul id="imagegallery">
<li>
<a href="./img/animals/1.jpg" title="Cat display">Cat</a>
</li>
...
</ul>
- 添加事件处理函数
此函数将完成:- 检查当前浏览器是否理解getElementByTagName,getWElementById
- 检查网页是否存在一个id为imagegallery的元素。
- 遍历imagegrller元素中的所有链接
- 设置onclick事件,让它在有关链接被点击时完成:把链接作为参数传递给showPic函数;取消链接点击的默认行为,不让浏览器打开此链接。
代码:
function prepareGallery(){
// 检查点
if(!document.getElementsByTagName) return false;
if(!document.getElementById) return false;
if(!document.getElementById("imagegallery")) return false;
// 变量
var gallery = document.getElementById("imagegallery");
var links = gallery.getElementsByTagName("a");
// 遍历
for(var i=0;i<links.length;i++){
// 改变行为
links[i].onclick =function(){
showPic(this);
return false;
}
}
}
-
利用onload,让prepareGallery函数在网页加载完毕后执行。
常规方法:
window.onload=function{
firstfunction();
...
}
弹性最佳的解决方案addLoadEvent步骤如下:
1. 把现有onload事件处理函数的值存入onload。
2. 若还没有绑定函数,则把新函数添加给它。(window.onload=firstfunction;)
3. 若已经绑定了若干函数,则把新函数追加到现有指令的末尾。
function addLoadEvent(func){
var oldonload=window.onload;
if(typeof window.onload != 'function'){
window.onload=func;
}else{
window.onload = function(){
oldonload();
func();
}
}
}
此时只需添加以下代码即可。
addLoadEvent(prepareGallery);
6.4 太多假设
原代码利用getElementById函数但是并没有判断元素是否存在,由此给showPic函数增加检查,代码如下。
function showPic(whichpic){
if(!document.getElementById("placeholder")) return false;
var sourse=whichpic.getAttribute("href");
var placeholder=document.getElementById("placeholder");
placeholder.setAttribute("src",sourse);
if(document.getElementById(description)){
var text=whichpic.getAttribute("title");
var description=document.getElementById("description");
description.firstChild.nodeValue=text;
}
return true;
}
showPic函数改进后,不再假设有关标记文档中肯定 存在着placeholder图片和description元素。即使文档中不存在这两个元素也不会发生JavaScript错误。
但仍然存在问题,若把placeholder图片删掉并刷新页面,链接将失效,脚本将 不能平稳退化。问题在于prepareGallery函数假设showPic函数一定会正常返回,进而取消了onclick的默认行为。
其实,是否要返回false以取消onclick的默认行为应该由showPic函数决定:
- 若图片返回成功,返回true;
- 若图片切换失败,返回false。
prepareGalley函数改进如下:
function prepareGallery(){
if(!document.getElementsByTagName) return false;
if(!document.getElementById) return false;
if(!document.getElementById("imagegallery")) return false;
var gallery = document.getElementById("imagegallery");
var links = gallery.getElementsByTagName("a");
for(var i=0;i<links.length;i++){
// 返回值由showPic决定
links[i].onclick =function(){
return !showPic(this);
}
}
}
6.5 优化
showPic函数中仍存在需要处理的假设:每个链接都有title属性,placeholder为一张图片。
解决:
function showPic(whichpic){
if(!document.getElementById("placeholder")) return false;
var sourse=whichpic.getAttribute("href");
var placeholder=document.getElementById("placeholder");
//检查placeholder是否为图片
if(placeholder.nodeName != "IMG") return false;
placeholder.setAttribute("src",sourse);
if(document.getElementById(description)){
//三目运算符简写if/else
var text=whichpic.getAttribute("title")? whichpic.getAttribute("title") : "";
var description=document.getElementById("description");
// 文本节点的nodeType属性值等于3
if(description.firstChild.nodeType == 3){
description.firstChild.nodeValue=text;
}
}
return true;
}
6.6 键盘访问
onkeypress事件处理函数用于处理键盘事件,但最好不要使用,因为用户每按下一个键都会触发它,若绑定在onkeypress的事件处理函数返回false,只使用键盘的用户将永远无法离开当前链接,没有保证JavaScript代码的可访问性。
用Tab键移动到某个链接然后按下回车也会触发onclick事件。
6.7 结合JavaScript和CSS
分离JavaScript和HTML文档还有一点好处:为元素加入的id可以用于CSS选择器。
6.8 DOM Core和HTML-DOM
至此,用到的DOM方法包括
- getElementById
- getElementByTagName
- getAttribute
- setAttribute
这几个方法是DOM Core的组成部分,不专属于JavaScript,支持DOM的程序设计语言都可以使用,如XML。
在使用JavaScript和DOM为HTML文档编写脚本还有许多属性可供选择,如onclick等,这些属性属于HTML-Core,早于DOM Core。
如:
document.getElementByTagName(“form”)可简化为document.forms
element.getAttribute(“src”)可简化为element.src。
一般HTML-DOM代码会更短,但只能用于处理Web文档。
6.9 小结
- 引入测试和检查,使JavaScript代码不依赖于没有保证的假设。
- 不使用onkeypress事件处理函数,保证JavaScript代码的可访问性。
- 从HTML文档中分离事件处理函数,使得JavaScript代码不依赖于HTML文档的内容和结构。结构和行为的分离程度越大越好。
- 仍存在需要改进的地方:placeholder和description元素只为了showPic存在,不支持禁用JavaScript 的浏览器也会显示它们,给访问者带来不便:让他们只在遇到支持DOM的浏览器时才出现在HTML文档中。