JavaScript美术馆

2012年4月2日 发表评论 阅读评论

来源:http://blog.tiantiansoft.com/user1/9/archives/2007/4484.html

《JavaScript DOM编程艺术》看完了,整个书一共十二章,前七章一直是用“JavaScript美术馆”做例子讲的,一直在改进这个美术馆,到第七章完结

在这七章书里,我最大的东西学到的是“预留退路”和“把结构和行为彻底分开”

在页面里调用js,我们以前最经常使用的是这两种情况:

<a href="javascript:showPic(‘aaa.jpg’);">aaa</a>

<a href="#" onclick="showPic(‘aaa.jpg’);">aaa</a>

有时候,如果在showPic里出现了错误,函数还没有执行到最后的return false;就遇错退出时,页面会被重新load一次,因为href="#",所以load的是本页面

有时候,浏览器禁用了js,我们设置的东西,就根本不会被执行

书里在一开始就一直强调,写js要“预留退路”,要考虑到可能出现的问题,要为每一个问题想好退路,书里在最开始的时候就使用了像这样子的写法:

<a href="/aaa.jpg" onclick="showPic(‘aaa.jpg’); return false;">aaa</a>

如果浏览器禁用了js,用户可以直接转到图片上查看,如果showPic有执行语句出错,脚本自己下一步就会执行return false,页面不会被转到另一个地方

还有就是“把结构和行为彻底分开”,书里一直到第七章,才最后把他们彻底分开,这种分开,包括js中需要使用到的容器标签、事件Event的触发全都放到js里控制了,页面的html代码里,只有完整的结构,没有函数的调用

下面记录我跟着书本学习时,到第六章结束的美术馆代码

showPic.js

/*
P92把多个JavaScript函数绑定到onload事件处理函数上
因为每个事件处理函数只能绑定一条指令,所以,如果有两个函数要逐一绑定到onload事件上:
window.onload = firstFunction;
window.onload = secondFunction;
它们当中只有最后那个才会被执行,secondFunction会取代firstFunction
解决办法一:创建匿名函数容纳这两个函数:
window.onload = function {
    firstFunction();
    secondFunction();
}
解决办法二:Simon Willison(http://simon.incutio.com)写的函数addLoadEvent
*/
function addLoadEvent(func)
{
    var oldonload = window.onload;
    if(typeof window.onload != ‘function’)
    {
        window.onload = func;
    }
    else
    {
        window.onload = function()
        {
            oldonload();
            func();
        }
    }
}

/*
insertBefore()方法将一个新元素插入到一个现有元素的前面,语法:parentElement.insertBefore(newElement, targetElement)
如:
var gallery = document.getElementById("Imagegallery");
gallery.parentNode.insertBefore(placeholder, gallery); //gallery.parentNode就是targetElement(gallery)的父节点
因为DOM没有提供insertAfter方法,所以要自己编写:
1、如果目标元素是他的parent元素的最后一个子元素,他后面没有下一个子元素了,直接把新节点追加到parent的最后
2、目标元素不是parent的最后一个子元素,就在目标元素的下一个元素targetElement.nextSibling前插入
if(parent.lastChild == targetElement)
*/
function insertAfter(newElement, targetElement)
{
    var parent = targetElement.parentNode;
    if(parent.lastChild == targetElement)
    {
        parent.appendChild(newElement);
    }
    else
    {
        parent.insertBefore(newElement, targetElement.nextSibling);
    }
}

function preparePlaceholder()
{
    //检查浏览器是不是支持这些方法,检查dom里有没有imagegallery节点
    if(!document.createElement) return false;
    if(!document.createTextNode) return false;
    if(!document.getElementById) return false;
    if(!document.getElementById("imagegallery")) return false;
   
    //显示图片的容器img标签
    var placeholder = document.createElement("img");
    placeholder.setAttribute("id", "placeholder");
    placeholder.setAttribute("src", "../images/placeholder.gif");
    placeholder.setAttribute("alt", "my image gallery");
   
    //显示文字描述的p标签
    var description = document.createElement("p");
    var desctext = document.createTextNode("Choose an image");
    description.setAttribute("id", "description");
    description.appendChild(desctext);
   
    //把两个标签加入dom节点树
    var gallery = document.getElementById("imagegallery");
    insertAfter(placeholder, gallery);      //把图片容器加到图片列表后面
    insertAfter(description, placeholder); //把文字描述加到图片容器的后面
    //insertAfter(description, gallery);    //把描述文字的p标签加入到图片列表的最后
    //description.parendNode.insertBefore(placeholder, description); //把显示图片的img标签加入到文字描述的前面
}

function prepareGallery()
{
    if(!document.getElementsByTagName) return false;
    if(!document.getElementById) return false;
    if(!document.getElementById("imagegallery")) return false;
   
    //取图片列表里所有a元素
    var gallery = document.getElementById("imagegallery");
    var links = gallery.getElementsByTagName("a");
    //给每一个a元素添加onclick事件
    for(var i = 0; i< links.length; i++)
    {
        links[i].onclick = function() {
            return showPic(this);
        }
        //links[i].onkeypress = links[i].onclick;
    }
}

/*
nodeType属性总共有12种可取值,但其中仅有3种具有实用价值:元素节点、属性节点和文本节点
元素节点属性值是:1
属性节点属性值是:2
文本节点属性值是:3

如果读取或设置文本节点的值,使用nodeValue属性:node.nodeValue
元素节点的nodeValue值为null,因为文本节点肯定是元素节点的子节点
如果要取<p>元素的文本,可以检索他的第一个子节点的nodeValue:node.childNodes[0].nodeValue

元素的第一个子节点:node.firstChild = node.childNodes[0]
元素最后一个子节点:node.lastChild = node.childNodes[node.childNodes.length - 1]
元素的所有子节点:childNodes
元素的父节点:parentNode
下一个节点:nextSibling
前一个节点:previousSibling
*/
function showPic(whichpic)
{
    //检查placeholder和description是不是存在,这两个元素是preparePlaceholder方法里加入的
    if(!document.getElementById("placeholder")) return true;
    if(!document.getElementById("description")) return false;
   
    //修改图片容器里的img.src指向当前链接的href属性值
    var source = whichpic.getAttribute("href");
    var placeholder = document.getElementById("placeholder");
    placeholder.setAttribute("src", source);
   
    //修改文本描述里的文本为当前链接的title属性值
    var text = "";
    var description = document.getElementById("description");
    if(whichpic.getAttribute("title"))
    {
        text = whichpic.getAttribute("title");
    }
    if(description.firstChild.nodeType == 3)
    {
        description.firstChild.nodeValue = text;
    }
    return false;
}

addLoadEvent(preparePlaceholder);
addLoadEvent(prepareGallery);

gallery.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>Image Gallery</title>
    <script type="text/javascript" src="/showPic.js"></script>
    <link rel="stylesheet" href="../styles/layout.css" type="text/css" media="screen" />
</head>
<body>
    <h1>Snapshots</h1>
    <ul id="imagegallery">
        <li>
            <a href="../images/fireworks.jpg" title="A fireworks display">
                <img src="../images/fireworks.jpg" alt="Fireworks" />
            </a>
        </li>
        <li>
            <a href="../images/coffee.jpg" title="A cup of black coffee">
                <img src="../images/coffee.jpg" alt="Coffee" />
            </a>
        </li>
        <li>
            <a href="../images/rose.jpg" title="A red, red rose">
                <img src="../images/rose.jpg" alt="Rose" />
            </a>
        </li>
        <li>
            <a href="../images/bigben.jpg" title="A famous clock">
                <img src="../images/bigben.jpg" alt="Big Ben" />
            </a>
        </li>
    </ul>
</body>
</html>

layout.css

body {
font-family: "Helvetica","Arial",serif;
color: #333;
background-color: #ccc;
margin: 1em 10%;
}
h1 {
color: #333;
background-color: transparent;
}
a {
color: #c60;
background-color: transparent;
font-weight: bold;
text-decoration: none;
}
ul {
padding: 0;
}
li {
float: left;
padding: 1em;
list-style: none;
}
#imagegallery {
list-style: none;
}

#imagegallery li {
display: inline;
}

#imagegallery li a img {
border: 0;
}

#imagegallery img { width:150px; }


转载请注明来自:[MSN Spaces]http://msn.shandian.biz/355.html

  1. 本文目前尚无任何评论.