运用JavaScript编程最佳实践改进一个图片库

如下:原始的JavaScript图片库
这里写图片描述
JavaScript代码如下:

function showPic(whichpic){
    var source=whichpic.getAttribute("href");
    var placeholder=document.getElementById("placeholder");
    placeholder.setAttribute("src",source);
    var text=whichpic.getAttribute("title");
    var description=document.getElementById("description");
    description.firstChild.nodeValue=text;
}

调用此函数的HTML文件:

<!DOCTYPE html>
<html>
<head>
    <title>Image Gallery</title>
</head>
<body>
    <h1>Snapshots</h1>
    <ul>
        <li>
            <a href="images/1.jpg" title="美丽的风景一" onclick="showPic(this);  return false;">风景一</a>
        </li>
        <li>
            <a href="images/2.jpg" title="美丽的风景二" onclick="showPic(this); return false;">风景二</a>
        </li>
        <li>
            <a href="images/3.jpg" title="美丽的风景三" onclick="showPic(this); return false;">风景三</a>
        </li>
        <li>
            <a href="images/4.jpg" title="美丽的风景四" onclick="showPic(this); return false;">风景四</a>
        </li>
    </ul>
    <img id="placeholder" src="images/5.jpg" alt="my image gallery"/>
    <p id="description">choose an image.</p>
    <script src="scripts/showPic.js"></script>
</body>
</html>

问题:我们将从平稳退化,向后兼容,分离JavaScript这几方面来改进
一:是否支持平稳退化
如果用户的浏览器禁用了JavaScript功能会怎样?通过检查代码,我们的脚本已经为此留出了退路,即使JavaScript功能被禁用,用户也可以浏览图片库里的图片,所有链接正常工作。只不过用户体验会比JavaScript差一点,但网页的基本内容并未受到损害。

    <li>
        <a href="images/1.jpg" title="美丽的风景一" onclick="showPic(this);  return false;">风景一</a>
    </li>

图片库通过了第一个测试。

二:它的JavaScript与HTML标记是分离的吗

    <li>
        <a href="images/1.jpg" title="美丽的风景一" onclick="showPic(this);  return false;">风景一</a>
    </li>

如上图片库的代码,明显网页的行为层(JavaScript)与其结构层(HTML)混杂在一起。
我们可以给图片库的每一个链接里添加一个class属性将JavaScript代码与HTML文档关联起来,但是分别添加事件处理函数很麻烦,所以我们可以给整个清单设置一个独一无二的ID要简单的多。

    <ul id="imagegallery">
        <li>
            <a href="images/1.jpg" title="美丽的风景一" onclick="showPic(this);  return false;">风景一</a>
        </li>
        ...
    </ul>

(1)添加事件处理函数
现在需要编写一个简短的函数把有关操作关联到onclick事件上,命名为prepareGallery,下面是我想让这个函数完成的工作:
检查当前浏览器是否理解getElementsByTagName;
检查当前浏览器是否理解getElementById;
检查当前网页是否出存在一个id为imagegallery的元素;
遍历imagegallery元素中的所有链接;
设置onclick事件,让它在有关链接被点击时完成以下操作:把这个链接作为参数传递给showPic函数,取消链接被点击时的默认行为,不让浏览器打开这个链接;
按这个过程完成JavaScript函数:

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; //阻止浏览器打开默认链接行为
        }
    }
}

(2)共享onload事件
如果在HTML文档完成加载之前执行脚本,此时的DOM是不完整的,我们应该让prepareGallery函数在网页加载完毕之后立刻执行,网页加载完毕会触发一个onload事件,这个事件与window对象相关联,为了让事态的发展不偏离计划,必须把prepareGallery函数绑定到这个事件上,若要加载完毕时执行多个函数可以用addLoadEvent函数:

//页面加载完毕时执行函数
function addLoadEvent(func) {
    var oldonload=window.onload; //把现有的window.onload事件处理函数的值存入变量
    if (typeof window.onload!='function') {
        window.onload=func;  //若事件处理函数还未绑定函数,将新函数添加给它
    }else{
        window.onload=function(){ //若已经绑定了,就将新函数添加到现有指令的末端
            oldonload();
            func();
        }
    }
    // body...
}

上面addLoadEvent函数可将页面加载完毕时执行的函数创建为一个队列,当我们执行函数prepareGallery时只需写出下面这行代码:

addLoadEvent(prepareGallery);

三.不要做太多假设
我们需要增加一些语句检查元素placeholder和description是否存在:

function showPic(whichpic){
    if (!document.getElementById("placeholder")) return false;  //函数必须完成的任务
    var source=whichpic.getAttribute("href");
    var placeholder=document.getElementById("placeholder");
    placeholder.setAttribute("src",source);
    if (document.getElementById("description")) {  //这个描述属于锦上添花
        var text=whichpic.getAttribute("title");
        var description=document.getElementById("description");
        description.firstChild.nodeValue=text;
    }
    return true;
} 

但是又有一个问题,当把placeholder图片从标记文档里删掉再刷新页面,就会出现无论点击imagegallery清单里哪一个链接都没有响应,这说明不能平稳退化,因此我们要以showPic()函数的返回值设置onclick事件的默认行为:

links[i].onclick=function(){
    return !showPic(this);  //图片切换成功返回true,切换不成功返回false
}

四.优化
我们对showPic()函数进行优化,假设每个链接都有一个title,那么我们要检查title属性是否真的存在,存在就返回true,并且text变量被赋值为title值;若不存在,返回false,则text将被赋值为一个空字符串(“ ”)。

if (whichpic.getAttribute("title")){
    var text=whichpic.getAttribute("title");
}else{
    var text="";
}

或者另一种方法:

var text=whichpic.getAttribute("title")?whichpic.getAttribute("title"):" "; //?是一个三元运算符,问号后面是变量的两种可能取值

五.键盘访问
在showPic()函数中,链接都是通过鼠标点击实现,然而有些人更喜欢使用键盘来点击,我们可以通过tab键从这个链接移动到另一个链接,然后按下回车键启用当前连接,有个onkeypress的事件处理函数专门用来处理键盘事件:

links[i].onclick=function(){
    return showPic(this)?false:true;
}
links[i].onkeypress=links[i].onclick;

但是我们一般不用onkeypress事件处理函数,因为这将会使那些只使用键盘访问的用户将永远无法离开当前链接。而onclick事件处理函数已经能满足需要,且它对键盘访问的支持相当完美。

六.把JavaScript与CSS结合起来
关于CSS的用法在这里将不再详述。

七.DOM Core和HTML-DOM
以上javascript代码只用到以下几个DOM方法:

getElementById
getElementsByTagName
getAttribute
setAttribute

这些都是DOM Core的组成部分,它们并不专属于Javascript,支持DOM的任何一种程序设计语言都可以使用它们。
在使用javascript语言和DOM为HTML文件编写脚本时,还有很多属性可供选择,例如onclick,这些属性属于HTML-DOM,它在DOM Core出现之前 就已经被人们熟悉,HTML-DOM可以将如下语句简化:

document.getElementsByTagName("form");  简化为:document.forms
element.getAttribute("src"); 简化为:element.src
var source=whichpic.getAttribute("href"); 简化为 var source=whichpic.href
placeholder.setAttribute("src",source); 简化为 placeholder.src=source;

一般DOM Core方法更容易使用,但可以根据个人喜好和具体情况作出选择。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值