《JavaScript DOM编程艺术》书中的图片库的总结(2)

前言:在《JavaScript DOM编程艺术》中初步实现的图片库的总结(1)中,有很多不足之处:比如事件处理嵌套在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 != &#x27;function&#x27;){
        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
https://segmentfault.com/a/1190000005727930
/blockquote>

1.本文由杨琼博客整理发布,部分文章来自网络,如有侵犯权益,请联络博主,资源失效和内容勘误欢迎留言.

2.转载请注明本文地址:http://www.iyangqiong.com/web/486.html

3.订阅更新:您可以通过 RSS订阅本站

【推荐!必备网址导航】http://longmiao.wang/

分享到:
顶部 评论 底部