JavaScript DOM编程艺术 读书笔记

 2. JavaScript语法

2.1 注释
     HTML允许使用"<!--"注释跨越多个行,但JavaScript要求这种注释的每行都必须在开头加上"<!--"来作为标志。JavaScript解释器对"<!--"的处理与对"//"的处理是一样的。
2.2 变量
     在JavaScript语言中,变量和其他语法元素的名字都是区分字母大小写的。
     JavaScript语法不允许变量中包含空格或标点符号(美元符号"$"例外)。JavaScript变量名允许包含字母、数字、美元符号和下划线(但第一个字符不允许是数字)。
2.3 数据类型
     JavaScript不需要进行类型声明,它是一种弱类型(weakly typed)语言。程序员可以在任何阶段改变变量的数据类型。
     字符串:如果想用双引号来包住一个本身就包含双引号的字符串,就必须使用反斜线对字符串中的双引号进行转义,例:var height = "about 5'10\" tall";
     数组:var beatles = Array("John","Paul","George","Ringo");或var beatles = ["John","Paul","George","Ringo"];
     在JavaScript中,所有的变量实际上都是某种类型的对象。比如,一个布尔值就是一个Boolean类型的对象,一个数组就是一个Array类型的对象。
     对象:var lennon={name:"John",year:1940,living:false};
     

3. DOM(document、object、model )

     5个常用DOM方法:getElementById、getElementsByTagName、getElementsByClassName、getAttribute和setAttribute
     JavaScript语言里的对象可以分为三种类型:(1)用户定义对象;(2)内建对象;(3)宿主对象;
3.4 结点
     DOM中包含的节点主要分为三种:元素节点、文本节点和属性节点。DOM的原子是元素节点,标签的名字就是元素的名字,元素可以包含其他的元素。没有被包含在其他元素里的唯一元素是<html>元素,它是树节点的根元素;
     在XHTML文档里,文本节点总是被包含在元素节点的内部。但并非所有的元素节点都包含有文本节点;
     属性节点用来对元素做出更具体地描述。属性总是被放在起始标签里,所以属性节点总是被包含在元素结点里。并非所有的元素都包含属性,但所有的属性都被元素包含。

  有3种DOM方法可获取元素节点,分别是通过元素ID、通过标签名字和通过类名字来获取。

  1) getElementById(id)

  2) getElementByTagName(tag):返回一个对象数组,每个对象分别对应着文档里有着给定标签的一个元素。

  3) getElementByClassName(class):HTML5 DOM,某些DOM实现里可能还没有;返回一个具有相同类名的元素的数组。

  获取属性和方法:object.getAttribute(attribute),object.setAttribute(attribute, value)。getAttribute方法与setAttribute方法不属于document对象,所以不能通过document对象调用,它只能通过元素节点对象调用。
function getElementsByClassName(node, classname){
    if(node.getElementsByClassName){
        return node.getElementsByClassName(classname);
    } else {
        var result = new array();
        var elements = getElementsByTagName("*");
        for(var i=0; i<elements.length; i++){
            if(elements[i].clsssName.indexOf(classname) != -1){
                result[result.length] = elements[i];
            }
        }
        return false;
    }
}

 

4. 案例研究:JavaScript图片库

  childNodes属性获取任何一个元素的所有子元素,它是一个包含这个元素全部子元素的数组:element.childNodes。通过element.childNodes.length获取element元素包含的元素的个数。由childNodes属性返回的数组包含所有类型的节点,而不仅仅是元素节点。事实上,文档里几乎每一样东西都是一个节点,甚至连空格和换行符都会被解释为节点,而它们也全都包含在childNodes属性所返回的数组当中。

  nodeType属性可以查看到节点类型,但其返回值是一个数字而不是“element”或“attribute”那样的英文字符串。nodeType属性共有12种可取值,但其中仅有3种具有实用价值:

  1)元素节点的nodeType属性值是1;

  2)属性节点的nodeType属性值是2;

  3)文本节点的nodeType属性值是3;

     如果想改变一个文本节点的值,可以使用DOM提供的node.nodeValue属性,它用来得到(和设置)一个节点的值。
     访问数组的第一个元素childNodes[0],也可以使用更直观的node.firstChild,与之对应的node.lastChild表示数组的最后一个元素,它其实是node.childNodes[node.childNodes.length-1]。  
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;}
img {display:block; clear:both;}
layout.css
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Image Gallery</title>
        <link rel="stylesheet" href="../css/layout.css" media="screen" />
    </head>
    <body>
        <h1>Snapshots</h1>
        <ul>
            <li><a href="../images/1.jpg" onclick="showPic(this);return false;" title="A firework display">Fireworks</a></li>
            <li><a href="../images/2.jpg" onclick="showPic(this);return false;" title="A cup of black coffee">Coffee</a></li>
            <li><a href="../images/3.jpg" onclick="showPic(this);return false;" title="A red,red rose">Rose</a></li>
            <li><a href="../images/4.jpg" onclick="showPic(this);return false;" title="The famous clock">Big Ben</a></li>
        </ul>
        <img id="placeholder" src="../images/5.jpg" alt="my image gallery" />
        <p id="description">Choose an image.</p>
        <script type="text/javascript" src="../js/showPic.js"></script>
    </body>
</html>
gallery.html
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;
}

function countBodyChildren(){
    var body_element = document.getElementsByTagName("body")[0];
    //alert(body_element.childNodes.length); //子节点个数
    //alert(body_element.nodeType);    //节点类型
}

window.onload = countBodyChildren();
showPic.js

5. 最佳实践

5.1平稳退化 
     如果正确地使用了JavaScript脚本,就可以让访问者在他们的浏览器不支持JavaScript的情况下仍能顺利地浏览你的网站。这就是所谓的平稳退化(graceful degradation)。就是说,虽然某些功能无法使用,但最基本的操作仍能顺利完成。
     “javascript:”伪协议让我们通过一个链接来调用JavaScript函数。例如:<a href="javascript:pop();">Example</a>
     如果用一个“挂钩”,就像CSS机制里的class或id属性那样,把JavaScript代码调用行为与HTML文档的结构和内容分离开,网页就会健壮很多。
window.onload = prepareLinks;
function prepareLinks(){
     if(!document.getElementsByTagName) return false;  //向后兼容性
     var links = document.getElementsByTagName("a");
     for(var i=0;i<links.length;i++){
          if(links[i].getAttribute("class") == "popup"){
               links[i].onclick = function(){
                    popUp(this.getAttribute("href"));
                    return false;
               }
          }
     }     
}
function popUp(winURL){
     window.open(winURL,'popup','width=320,height=480');
}
show.js
     几个代表性的压缩工具:
(1)Douglas Crockford的JSMin(http://www.crockford.com/javascript/jsmin.html)
(2)雅虎的YUI Compressor(http://yui.github.io/yuicompressor/)
(3)谷歌的Closure Compiler(http://closure-compiler.appspot.com/home)

6. 案例研究:图片库改进版

     尽量让JavaScript代码不再依赖于那些没有保证的假设,为此引入了许多项测试和检查,使代码能够平稳退化。最重要的是事件处理函数从标记文档分离到一个外部的JavaScript文件,使JavaScript代码不再依赖于HTML文档的内容和结构。
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Image Gallery</title>
        <link rel="stylesheet" href="../css/layout.css" media="screen" />
    </head>
    <body>
        <h1>Snapshots</h1>
        <ul id="imagegallery">
            <li>
                <a href="../images/1.jpg" title="A firework display">
                    <img src="../images/1.jpg" alt="Fireworks" />
                </a>
            </li>
            <li>
                <a href="../images/2.jpg" title="A cup of black coffee">
                    <img src="../images/2.jpg" alt="Coffee" />
                </a>
            </li>
            <li>
                <a href="../images/3.jpg" title="A red,red rose">
                    <img src="../images/3.jpg" alt="Rose" />
                </a>
            </li>
            <li>
                <a href="../images/4.jpg" title="The famous clock">
                    <img src="../images/4.jpg" alt="Big Ben" />
                </a>
            </li>
        </ul>
        <img id="placeholder" src="../images/5.jpg" alt="my image gallery" />
        <p id="description">Choose an image.</p>
        <script type="text/javascript" src="../js/showPic.js"></script>
    </body>
</html>
gallery.html
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; width:80px; height:80px;}
img {display:block; clear:both;}
#imagegallery {list-style:none;}            
layout.css
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 prepareGallery(){
    if(!document.getElementsByTagName || !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(){
            return showPic(this) ? false : true;
        }
    }    
}

function addLoadEvent(func){
    var oldonload = window.onload;
    if(typeof window.onload != 'function'){
        window.onload = func;
    } else {
        window.onload = function(){
            oldonload();
            func();
        }
    }
}
addLoadEvent(prepareGallery);
showPic.js

 

7 动态创建标记

7.1 一些传统的方法
(1)document.write
     document对象的write()方法可以方便快捷的把字符串插入到文档里。例如:
function insertParamgraph(text){
    var str="<p>";
    str += text;
    str += "</p>";
    document.write(str);
}
demo
(2)appendChild方法 
     把刚创建的元素添加到ID为testdiv的DOM节点树中,成为它的子节点: 
var testdiv = document.getElementById("testdiv");
testdiv.appendChild(param);//把这个p元素节点追加到文档中的一个元素节点
demo
(3)createTextNode方法
     创建一个文本节点:
var txt = document.createTextNode("Hello World"); //创建一个文本节点
para.appendChild(txt); //把这个文本节点追加到刚创建的那个p元素节点上
demo
(4)insertBefore方法 
     insertBefore()方法把一个新元素插入到一个现有元素的前面。在调用此方法时,必须知道三件事:
     a:新目标,你想插入的元素(newElement);
     b:目标元素,你想把这个新元素插入到哪个元素(targetElement)之前;
     c:父元素,目标元素的父元素(parentElement);
     该方法的调用语法为:parentElement.insertBefore(newElement, targetElement)。我们不必搞清楚父元素到底是哪个,因为targetElement元素的parentNode属性值就是它。在DOM里,元素节点的父元素必须是另一个元素节点(属性节点和文本节点的子元素不允许是元素节点)。如下所示:
var gallery = document.getElementById("imagegallery");
gallery.parentNode.insertBefore(placeholder, gallery);
demo
  注意:DOM并没有提供insertAfter函数。但可以利用已有的DOM方法和属性编写的insertAfter函数,详见下文。

7.3 图片改进效果

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Image Gallery</title>
        <link rel="stylesheet" href="../css/layout.css" media="screen" />
    </head>
    <body>
        <h1>Snapshots</h1>
        <ul id="imagegallery">
            <li>
                <a href="../images/1.jpg" title="A firework display">
                    <img src="../images/1.jpg" alt="Fireworks" />
                </a>
            </li>
            <li>
                <a href="../images/2.jpg" title="A cup of black coffee">
                    <img src="../images/2.jpg" alt="Coffee" />
                </a>
            </li>
            <li>
                <a href="../images/3.jpg" title="A red,red rose">
                    <img src="../images/3.jpg" alt="Rose" />
                </a>
            </li>
            <li>
                <a href="../images/4.jpg" title="The famous clock">
                    <img src="../images/4.jpg" alt="Big Ben" />
                </a>
            </li>
        </ul>
        <script type="text/javascript" src="../js/showPic.js"></script>
    </body>
</html>
gallery.html
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 prepareGallery(){
    if(!document.getElementsByTagName || !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(){
            return showPic(this) ? false : true;
        }
    }    
}

function insertAfter(newElement, targetElement){
    var parent = targetElement.parentNode;
    if(parent.lastChild == targetElement) {
        parent.appendChild(newElement);
    } else {
        parent.insertBefore(newElement, targetElement.nextSibling);
    }
}

function preparePlaceholder(){
    if(!document.createElement) return false;
    if(!document.createTextNode) return false;
    if(!document.getElementById) return false;
    if(!document.getElementById("imagegallery")) return false;
    
    var placeholder = document.createElement("img");
    placeholder.setAttribute("id","placeholder");
    placeholder.setAttribute("src","../images/5.jpg");
    placeholder.setAttribute("alt","my image gallery");
    
    var description = document.createElement("p");
    description.setAttribute("id","description");
    var desctext = document.createTextNode("Choose an image");
    description.appendChild(desctext);
    var gallery = document.getElementById("imagegallery");
    insertAfter(placeholder, gallery);
    insertAfter(description,placeholder);
}

function addLoadEvent(func){
    var oldonload = window.onload;
    if(typeof window.onload != 'function'){
        window.onload = func;
    } else {
        window.onload = function(){
            oldonload();
            func();
        }
    }
}

addLoadEvent(preparePlaceholder);
addLoadEvent(prepareGallery);
viewPic.js

7.4 Ajax技术

     DEOM之html代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>Ajax</title>
        <link rel="stylesheet" href="../css/layout.css" media="screen" />
    </head>
    <body>
        <div id="new"></div>
        <script type="text/javascript" src="../js/addLoadEvent.js"></script>
        <script type="text/javascript" src="../js/getHTTPObject.js"></script>
        <script type="text/javascript" src="../js/getNewContent.js"></script>
    </body>
</html>
ajax.html
     DEMO之getHTTPObject.js代码:
function getHTTPObject() {
    if(typeof XMLHttpRequest == "undefined") {
        XMLHttpRequest = function() {
            try{
                return new ActiveXObject("Msxml2.XMLHTTP.6.0");
            } catch(e){
            }
            
            try{
                return new ActiveXObject("Msxml2.XMLHTTP.3.0");
            } catch(e){
            }
            
            try{
                return new ActiveXObject("Msxml2.XMLHTTP");
            } catch(e){
            }
            return false;
        }
    }
    return new XMLHttpRequest();
}
View Code
     XMLHttpRequest对象有许多的方法。其中最有用的是open方法,它用来指定服务器上要访问的文件,指定请求类型:GET、POST或SEND。这个方法的第三个参数用于指定请求是否以异步方式发送和处理。getNewContent.js代码如附件所示。
     代码中的onreadystatechange是一个事件处理函数,它会在服务器给XMLHttpRequest对象送回响应的时候被触发执行。在这个处理函数中,可以根据服务器的具体响应做相应的处理。
     服务器在向XMLHttpRequest对象发回响应时,该对象有许多属性可用,浏览器会在不同阶段更新readyState属性的值。它有5个可能的值:
     a:0表示未初始化;
     b:1表示正在加载;
     c:2表示加载完毕;
     d:3表示正在交互;
     e:4表示完成;
     只要readyState属性值变成了4,就可以访问服务器发送回来的数据了。
     DEMO之getNewContent.js代码:
function getNewContent() {
    var request = getHTTPObject();
    if(request) {
        request.open("GET", "../views/example.txt", true); //发起一个GET请求,请求的是example.txt的内容
        request.onreadystatechange = function() { //响应处理函数
            if(request.readyState == 4) {
                alert("Response Received");
                var para = document.createElement("p");
                var txt = document.createTextNode(request.responseText);
                para.appendChild(txt);
                document.getElementById("new").appendChild(para);
            }
        };
        request.send(null); //发送请求
    } else { //若浏览器不支持XMLHttpRequest对象
        alert("Sorry, your browser doesn\'t support XMLHttpRequest");
    }
    alert("Function Done");
}
addLoadEvent(getNewContent);
getNewContent.js
     访问服务器送回来的数据要通过两个属性完成。一个是responseText属性,这个属性保存文本字符串形式的数据。另一个属性是responseXML属性,用于保存Content-Type头部中指定为“text-xml”的数据,其实是一个DocumentFragment对象,可以使用各种DOM方法来处理这个对象。
  异步请求有一个容易被忽略的问题是异步性,就是脚本在发送XMLHttpRequest请求后,仍然会继续执行,不会等待相应返回。
 

8 充实文档内容

8.4 为文档创建缩略语列表的函数

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Ajax</title>
        <link rel="stylesheet" media="screen" href="../css/typegraphy.css" />
    </head>
    <body>
        <h1>What is the document object model?</h1>
        <p>
            The <abbr title="World Wide Web Consortium">W3C</abbr> defines the 
            <abbr title="Document Object Model">DOM</abbr> as:
        </p>
        <blockquote cite="http://www.w3c.org/DOM/">
            <p>
                A platform- and language-neutral interface that will allow programs and scripts to
                dynamically access and update the content, structure and style of documents.
            </p>
        </blockquote>
        <p>
            It is an <abbr title="Application Programing Interface">API</abbr> that can be used to
            navigate <abbr title="HyperText Markup Language">HTML</abbr> and <abbr title="Extensible
                Markup Language">XML</abbr> documents.
        </p>
        <script src="../js/addLoadEvent.js"></script>
        <script src="../js/displayAbbreviations.js"></script>
    </body>
</html>
explanation.html
function displayAbbreviations(){
    //兼容性检测
    if(!document.getElementsByTagName) return false;
    if(!document.createElement) return false;
    if(!document.createTextNode) return false;
    
    //取得所有缩略词
    var abbreviations = document.getElementsByTagName("abbr");
    if(abbreviations.length < 1) return false;
    
    //遍历缩略词
    var defs = new Array();
    for(var i=0;i<abbreviations.length;i++){
        var current_abbr = abbreviations[i];
        if(current_abbr.childNodes.length < 1) continue;
        var definition = current_abbr.getAttribute("title");
        var key = current_abbr.lastChild.nodeValue;
        defs[key] = definition;
    }
    
    //创建定义列表
    var dlist = document.createElement("dl");
    for(key in defs){
        var definition = defs[key];
        
        //创建定义标题
        var dtitle = document.createElement("dt");
        var dtitle_text = document.createTextNode(key);
        dtitle.appendChild(dtitle_text);
        
        var ddesc = document.createElement("dd");
        var ddesc_text = document.createTextNode(definition);
        ddesc.appendChild(ddesc_text);
        
        //把他们添加到定义列表
        dlist.appendChild(dtitle);
        dlist.appendChild(ddesc);
    }
    if(dlist.childNodes.length < 1) return false;
    
    //创建标题
    var header = document.createElement("h2");
    var header_text = document.createTextNode("Abbreviations");    
    header.appendChild(header_text);
    
    //把标题添加到页面主题
    document.body.appendChild(header);
    //把定义列表添加到页面主题
    document.body.appendChild(dlist);
}

addLoadEvent(displayAbbreviations);
displayAbbreviations.js

 8.5 显示文献来源链接表

function displayCitations(){
    var quotes = document.getElementsByTagName("blockquote");
    for(var i=0;i<quotes.length;i++){
        if(!quotes[i].getAttribute("cite")) {
            continue;
        }
        var url = quotes[i].getAttribute("cite");
        var quoteChildren = quotes[i].getElementsByTagName("*");
        if(quoteChildren.length < 1) continue;
        var elem = quoteChildren[quoteChildren.length-1];
        var link = document.createElement("a");
        var link_text = document.createTextNode("source");
        links.appendChild(link_text);
        links.setAttribute("href",url);
        var superscript = document.createElement("sup");
        superscript.appendChild(links);
        elem.appendChild(superscript);
    }
}
displayCitations.js

8.6 显示“快捷键清单”

function displayAccessKeys(){
    if(!document.getElementsByTagName || !document.createElement || !document.createTextNode)
        return false;
    //取得文档中的所有链接
    var links = document.getElementsByTagName("a");
    //创建一个数组,保存访问键
    var akeys = new Array();
    for(var i=0;i<links.length;i++){
        var current_link = links[i];
        //如果没有accesskey属性,继续循环
        if(!current_link.getAttribute("accesskey")) continue;
        //获取accesskey的值
        var key = current_link.getAttribute("accesskey");
        //获取文本链接
        var text = current_link.lastChild.nodeValue;
        akeys[key] = text;
    }
    
    //创建列表
    var list = document.createElement("ul");
    //遍历访问键
    for(key in akeys) {
        var text = akeys[key];
        //创建放到列表项中的字符串
        var str = key + ":" + text;
        //创建列表项
        var item = document.createElement("li");
        var item_text = document.createTextNode(str);
        item.appendChild(item_text);
        //把列表项添加到列表
        list.appendChild(item);
    }
    //创建标题
    var header = document.createElement("h3");
    var header_text = document.createTextNode("Accesskeys");
    header.appendChild(header_text);
    
    //把标题添加到页面主体
    document.body.appendChild(header);
    //把列表添加到页面主体
    document.body.appendChild(list);
}
addLoadEvent(displayAccessKeys);
displayAccessKeys.js

 

 

9 CSS-DOM

  文档的每个元素节点都有一个属性style。style属性包含着元素的样式,查询这个属性将返回一个对象而不是一个简单的字符串。样式都存放在这个style对象的属性里:element.style.property。不仅文档里的每个元素都是一个对象,每个元素都有一个style属性,它们也是一个对象。

  当需要引用一个中间带减号的CSS属性时,DOM要求你用驼峰命名法。例如CSS属性font-family变为DOM属性fontFamily。且不管CSS样式属性的名字里有多少个连字符,DOM一律采用驼峰命名法表示它们。

  style对象只包含在HTML代码里用style属性声明的样式。在外部样式表和文档的<head>部分里声明的样式不会进入style对象。然而,style对象的各个属性都是可读写的,不仅可以通过某个元素的style属性去获取样式,还可以通过它去更新样式。虽然不应该利用DOM去创建重要的内容,但可以利用DOM对文档的样式做一些小增强。

  还可以用element.className = value来设置样式。

10 用javascript实现动画效果

  JavaScript函数setTimeout能够让某个函数在经过一段预定的时间之后才开始执行。该函数带有两个参数:第一个参数通常是一个字符串,其内容是将要执行的那个函数的名字;第二个参数是一个数值,它以毫秒为单位设定了需要经过多长时间后才开始执行第一个参数所给出的参数:setTimeout("function", interval); 在绝大多数时候,把这个函数调用赋值给一个变量将是个好主意:variable = setTimeout("function", interval);

  如果想取消某个正在排队等待执行的函数,就必须事先像上面这样把setTimeout函数的返回值赋值给一个变量。可以使用clearTimeout函数来取消”等待执行“队列里的某个函数。这个函数需要一个参数---保存着某个setTimeout函数调用返回值的变量。

  JavaScript允许我们为元素创建属性:element.property = value; 这很像是在创建一个变量,但区别是这个变量专属于某个特定的元素。

HTML代码:

<p id="message">Hello World!</p>

JS代码:

function moveElement(elementID, final_x, final_y, interval) {
    if(!document.getElementsByTagName || !document.createElement || !document.createTextNode)
        return false;
    if(!document.getElementById(elementID))
        return false;
    var elem = document.getElementById(elementID);
    if(elem.movement){
        clearTimeout(elem.movement);
    }
    if(!elem.style.left) 
        elem.style.left = "0px";
    if(!elem.style.top)
        elem.style.top = "0px";
        
    var xpos = parseInt(elem.style.left);
    var ypos = parseInt(elem.style.top);
  var dist = 0;
    if(xpos == final_x && ypos == final_y) {
        return true;
    }
    if(xpos < final_x){ 
    dist = Math.ceil((final_x - xpos)/10);
    xpos = xpos + dist;
  }
    if(xpos > final_x) {
    dist = Math.ceil((xpos - final_x)/10);
    xpos = xpos - dist;
  }
    
    if(ypos < final_y){
    dist = Math.ceil((final_y - ypos)/10);
    ypos = ypos + dist;
  }
    if(ypos > final_y){
    dist = Math.ceil((ypos - final_y)/10);
    ypos = ypos - dist;
  }
    
    elem.style.left = xpos + "px";
    elem.style.top = ypos + "px";
    var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")";
    elem.movement = setTimeout(repeat, interval);
}

 12 一些整理

 12.1 form对象

  文档中的每个表单元素都是一个form对象,每个form对象都有一个element.length属性。这个属性返回表番中的包含的表单元素的个数:form.elements.length。这个返回值与childNodes.length不一样,后者返回的是元素中包含的所有节点的个数。而form对象的elements.length属性只关心那些表单的元素,如input、textarea等等。

  相应的,表单中的所有字段都保存在form对象的elements属性中。也就是说,form.elements是一个包含所有表单元素的数组。同样,这个属性与childNodes属性也不一样,后者也是一个数组。childNodes数组返回的是所有节点,而elements数组则只返回input、select、textarea以及其他表单字段。

  elements数组中的每个表单元素都有自己的一组属性。比如:value属性中保存的就是表单元素的当前值:element.value,等价于element.getAttribute("value");

  

 

 

 

posted @ 2014-04-29 14:21  borage  阅读(543)  评论(0编辑  收藏  举报