1

前言:在《DOM编程艺术》中初步实现的图片库的总结(一)中,有很多不足之处:比如事件处理嵌套在HTML中,显得如此笨重和屌丝;没有对showPic函数进行相应的安全检查等,本篇文章对上述问题做了全面的升级。
--------------------开始---------------------

1.首先要把HTML部分进行改造

去掉嵌套在HTML中的事件处理代码,并且为了js能操作<ul>标签,需要对<ul>标签添加ID属性值


    <h1>电影天堂</h1>
    <ul id="filmlist">
        <li>
            <a href="images/01灰姑娘.jpg" title="灰姑娘">灰姑娘</a>
        </li>
        <li>
            <a href="images/02千与千寻.jpg" title="千与千寻">千与千寻</a>
        </li>
        <li>
            <a href="images/03哆啦A梦.jpg" title="哆啦A梦">哆啦A梦</a>
        </li>
        <li>
            <a href="images/04当幸福来敲门.jpg" title="当幸福来敲门">当幸福来敲门</a>
        </li>
    </ul>
    <!--占位符图片-->
    <img id="placeholder" src="images/placeholder.jpg" alt="hehehe">
    <!--一段描述-->
    <p id="description">选择一张图片</p>

2.获取<ul>标签中的节点a,遍历并且绑定事件处理


    function prepareFilm(){
        if(!document.getElementsByTagName){
            return false;
        }
        if(!document.getElementById){
            return false;
        }
        if(!document.getElementById("filmlist")){
            return false;
        }
        var list = document.getElementById("filmlist");
        var links = list.getElementsByTagName("a");
        for(var i = 0; i<links.length; i++){
            links[i].onclick = function(){
                showPic(this);
                return false;
            }
        }
    }

3.本例非必需:共享onload事件

本例中必须执行prepareFilm函数才能对onclick事件进行绑定,但是这个函数又不能在HTML文档加载之前执行,网页加载完毕时会触发一个onload事件,但是需要执行的函数有多个逐一添加又麻烦,而且后续的函数会覆盖上一个,所以就有必要封装一个addLoadEvent函数把将要执行的函数作为参数传进去,


    //共享onlond事件,封装成一个函数,@func是页面加载时需要执行的那个函数。
    //如果window.onload在页面加载时还没有绑定任何函数,就把需要执行的函数添加给它、
    //如果这个处理函数已经绑定了函数,就把新函数追加到现有指令的末尾
    function addLoadEvent(func){
        //把现有的window.onload存入变量oldonload
        var oldonload = window.onload;
        if(typeof window.onload != 'function'){
            window.onload = func;
        }else{
            window.onload = function(){
                oldonload();
                func();
            }
        }
    }

但是这个时候还有一些bug,就是没有对showPic函数进行必要的安全检查,而showPic函数要被prepareFilm函数调用,假如它获取不到图片呢?

4.对showPic函数进行安全检查

    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;
    }

但是还是有问题,就是此时prepareFilm函数做了一个假设:showPic函数肯定会正常返回,基于这一假设,prepareFilm函数在执行showPic函数时就会提前返回一个true,从而取消了onclick事件的默认行为。所以是否要返回一个false值取消onclick默认行为,应该由showPic函数决定,图片切换成功返回true,图片切换失败,返回false。
所以此时应该把prepareFilm函数最后两句改为:return !showPic(this);

5.添加更多的检查

(1)假设每个链接都有title属性,假如不存在把text值设置为空;

(2)placeholder是否存在?假设那是一张图片(本例中它确实是图片),为了验证这个情况,可以用nodeName属性增加这一项测试。

下面是添加更多的检查之后的showPic函数代码:


    function showPic(whichpic){
        if(!document.getElementById("placeholder")) return false;
        var source = whichpic.getAttribute("href");
        var placeholder = document.getElementById("placeholder");
        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.调用addLoadEvent函数

    //在页面加载完成后调用prepareFilm函数
    addLoadEvent(prepareFilm);

7.完整代码

老规矩,上完整源码

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>example</title>
    <style>
        h1 {
            color: #333;
        }
        
        a {
            color: gray;
            font-weight: bold;
            text-decoration: none;
        }
        
        ul {
            padding: 0;
        }
        
        li {
            float: left;
            padding: 1em;
            list-style-type: none;
        }
        
        img {
            display: block;
            clear: both;
        }
    </style>
</head>

<body>
    <h1>电影天堂</h1>
    <ul id="filmlist">
        <li>
            <a href="images/01灰姑娘.jpg" title="灰姑娘">灰姑娘</a>
        </li>
        <li>
            <a href="images/02千与千寻.jpg" title="千与千寻">千与千寻</a>
        </li>
        <li>
            <a href="images/03哆啦A梦.jpg" title="哆啦A梦">哆啦A梦</a>
        </li>
        <li>
            <a href="images/04当幸福来敲门.jpg" title="当幸福来敲门">当幸福来敲门</a>
        </li>
    </ul>
    <!--占位符图片-->
    <img id="placeholder" src="images/placeholder.jpg" alt="hehehe">
    <!--一段描述-->
    <p id="description">选择一张图片</p>

    <!--以下是js代码-->
    <script>
        function showPic(whichpic){
            if(!document.getElementById("placeholder")) return false;
            var source = whichpic.getAttribute("href");
            var placeholder = document.getElementById("placeholder");
            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;
        }

        function prepareFilm(){
            if(!document.getElementsByTagName){
                return false;
            }
            if(!document.getElementById){
                return false;
            }
            if(!document.getElementById("filmlist")){
                return false;
            }
            var list = document.getElementById("filmlist");
            var links = list.getElementsByTagName("a");
            for(var i = 0; i<links.length; i++){
                links[i].onclick = function(){
                    return showPic(this)?false:true;
                }
            }
        }

        //共享onlond事件,封装成一个函数,@func是页面加载时需要执行的那个函数。
        //如果window.onload在页面加载时还没有绑定任何函数,就把需要执行的函数添加给它、
        //如果这个处理函数已经绑定了函数,就把新函数追加到现有指令的末尾
        function addLoadEvent(func){
            //把现有的window.onload存入变量oldonload
            var oldonload = window.onload;
            if(typeof window.onload != 'function'){
                window.onload = func;
            }else{
                window.onload = function(){
                    oldonload();
                    func();
                }
            }
        }

        //在页面加载完成后调用prepareFilm函数
        addLoadEvent(prepareFilm);
    </script>
</body>

</html>

yangdepp
446 声望21 粉丝

只有那些疯狂的人才能引起我的兴趣,那些人疯狂地生活,疯狂地表达,同时对一切事物心怀渴望,他们毫无倦意,不屑于陈词滥调,只是燃烧,燃烧,燃烧。