【JavaScript DOM编程艺术】- 案例研究:JS图片库

HTML结构

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>图片库</title>
</head>
<body>
    <h1>轻图</h1>
    <ul id="gallery">
        <li>
            <a href="" title="">P1</a>
        </li>
        <li>
            <a href="" title="">P2</a>
        </li>
        <li>
            <a href="" title="">P3</a>
        </li>
    </ul>
    <img id="placeholder" src="placeholder.jpg" alt="图片库" />
    <p id="description"></p>
</body>
</html>

基本CSS

li{
    display: inline;
    margin-right: 2em;
}
a{
    text-decoration: none;
    color: red;
}
img{
    border: .2em solid red
}

想要实现的效果?

点击图片名,在placeholder上出现对应图片。
现状是点击图片名会跳转到单独的图片页面。
所以我们需要在点击图片名时:

  1. 不会打开单独图片页面。
  2. 图片出现在placeholder上。

操作步骤

  1. 获取点击图片的元素节点。
  2. 获取这个元素节点的href属性节点。
  3. 将href中的链接设置到img元素中的src属性中。

实现代码

function showPic(whichPic){
    var source = whichPic.getAttribute("href");
    var placeholder = document.getElementById("placeholder");
    placeholder.setAttribute("src", source);
}

事件处理函数

事件处理函数的作用是,在特定事件发生时调用特定的JS代码。
在给某个元素添加了事件处理函数后,一旦事件发生,相应的JS代码就会得到执行。被调用的JS代码可以返回一个值,这个值将被传递给那个事件处理函数。
例如当onclick事件时,点击链接会默认return true认为“链接被点击了“。而如果手动return false则不会默认打开窗口,但是代码依然会执行。

这样做的问题?

需要给每一个图片名标注onclick事件处理函数,这样就把结构行为混在了一起。为了把他们分离开来,我们在JS中重写onclick事件处理函数。

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

将title显示在图片下方

  1. 提取点击到的title。
  2. 将title赋值给图片下方p元素节点的文本节点。

提取

var text = whichPic.getAttribute("title");

如何插入?

childNodes属性
在一棵节点树上,childNodes表示一个元素的所有子元素,它是一个数组。

nodeType属性

  • 元素节点的nodeType属性值是1
  • 属性节点的nodeType属性值是2
  • 文本节点的nodeType属性值是3
    body.childNodes.length并不仅仅是元素节点,还包括属性节点和文本节点。

改写只获取元素节点数量函数

function countBodyChildren(){
    var num = 0;
    var body_element = document.getElementsByTagName("body")[0];
    for(var i=0; i<body_element.childNodes.length; i++){
        if(body_element.childNodes[i].nodeType == 1){
            num++;
        }
    }
    console.log(num);
}

nodeValue属性
如果想改变一个文本节点的值,则改变nodeValue的值。
然而改变的不该是元素节点的nodeValue,而是元素节点的文本子节点的nodeValue。
即:

var description = document.getElementById("description");
description.childNodes[0].nodeValue = "改变这个值";

firstChild和lastChild属性

node.firstChild == node.childNodes[0]
node.lastChild == node.childNodes[node.childNodes.length-1]

显示title在图片下方的代码

function showPic(whichPic){
    //原来的代码
    var description = document.getElementById("description");
    var text = whichPic.getAttribute("title");
    description.firstChild.nodeValue = text;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值