Javascript学习8 - 脚本化文档(Document对象)

简介: 原文:Javascript学习8 - 脚本化文档(Document对象)    每个Web浏览器窗口(或帧)显示一个HTML文档,表示这个窗口的Window对象有一个document属性,它引用了一个Document对象。
原文: Javascript学习8 - 脚本化文档(Document对象)

    每个Web浏览器窗口(或帧)显示一个HTML文档,表示这个窗口的Window对象有一个document属性,它引用了一个Document对象。
    一个文档对象模型或者说DOM就是一个API,它定义了如何访问组成一个文档的对象。W3C定义了一个标准的DOM,使用Document API,可以作用于HTML和XML文档的通用功能,添加特定于HTML的属性和方法。
    Document对象的详细属性可以见:http://www.w3school.com.cn/htmldom/dom_obj_document.asp

    8.1 Document属性
        cookie      : 允许Javascript程序读写HTTP cookie.
        lastModfied : 一个字符串,包含文档修改日期
        location    : 等价于URL,已经废弃。
        referrer    : 文档URL,包含把浏览器带到当前文档的链接。
        title       : 文档标记<title>之间的文本。
        URL         : 一个字符串,声明装载文档的URL。
    8.2 文档对象集合 【遗留DOM】
        anchors[]   : 文档中所有的锚
        applets[]   : 代表文档中的Java applet
        forms[]     : 代表文档中的form元素。
        images[]    : 所有<img>元素的集合
        links[]     : 所有超链接Link对象
        以上这些称之为遗留DOM集合,它们可以脚本化,但是,它们不能改变文档的结构。可以查看并修改链接的目标地址,从表单元素读取和写入值,但是,无法改变文档相互的结构。
    8.3 命名document对象
        一般来说,可以使用基于数字来索引文档对象集合元素,但是,基于位置索引不稳定,小的文档改变顺序可以破坏代码。
        所以,可以为文档元素分配名字,通过名字来引用这些元素。
        例如,以下form元素的访问:
            <form name="f1">....</form>
        可以这样访问:
            document.forms[0]  
        也可以这样:
            document.forms.f1 或者 document.forms["f1"]
       有以下表单
            <form name="shipping">  <input type="text" name="zipcode"> </form>
        可以做以访问:

1 document.forms[ 0 ].elements[ 0 ]
2 document.shipping.zipcode
    8.4 Document对象上的事件句柄
        在HTML中,把函数赋予一个事件句柄属性来定义它们,以下的HTML代码加下事件句柄:
            <form name="myform" onsubmit="return validateform();">...</form>
        除了在onsubmit中加入javascript函数外,也可以在JS中直接把函数赋予事件句柄属性
          
1 document.myform.onsubmit  =  validateform;    // 注意,不是调用函数,不需要()

    8.5 W3C DOM 节点
        W3C DOM 取代了遗留DOM,强大而标准化,在介绍DOM之前,有一些预备知识:
        ①需要把文档表示为树
            HTML文档在DOM中表示为对象的一棵树,树中有各种各样的节点,节点之上的节点是父节点(parent),直接位于一个节点下层的节点是子节点(children).位于同一层次的节点是兄弟节点(sibling).一个节点的下一个层次节点的集合是那个节点的扣代(descentdant).一个节点的父节点、祖父节点及其它所有位于其它的节点集合是那个节点的祖先(ancestor)
        ②节点Node
            一个节点表示为一个Node接口,Node接口定义了遍历和操作树的属性和方法。
            Node.childNodes 返回节点的孩子集合
            Node.firstChild,lastChild,nextSibling,previousSibling,parentNode 属性提供了遍历节点的树的一种方法
            Node.appendChild(), removeChild(),replaceChild(),insertBefore() 这些方法能够向一个文档树中添加节点或者移动节点。
        ③节点的类型
            每个Node对象都有一个nodeType属性,它指定了节点是什么类型。
            常见节点类型:
            Element             Node.ELEMENT_NODE               1
            Text                Node.TEXT_NODE                  3
            Document            Node.DOCUMENT_NODE              9
            Comment             Node.COMMENT_NODE               8
            DocumentFragment    Node.DOCUMENT_FRAGMENT_NODE     11
            Attr                Node.ATTRIBUTE_NODE             2
           DOM树部的Node是一个Document对象,这个对象的documentElemtn属性引用一个Element对象,它代表了文档的根元素。对于HTML文档,这是<html>标记。
            在一个DOM树中只有一个Document对象,DOM树的大部分节点是表示标记的Element对象和表示文本串的Text对象。
            DOM API的部门类分层图见15-2
        ④属性
            用Element接口的getAttribute()方法、SetAttribute()方法和RemoveAttribute()方法可以获得、增加、删除一个元素的属性(如img的src属性和width属性)

      8.6 DOM HTML API
            HTMLDocument是HTML专有的Document接口的子接子。HTMLElement是HTML专有的Element接口的子接口。另外,DOM为许多HTML元素定义了标记专有的接口,如HTMLBodyElement、HTMLTitleElement、HTMLInputElement...这些标记专有的接口通常定义了HTML标记属性的属性集合。
            ● HTMLDocument接口定义了支持各种文档的属性和方法,包括location、forms[]数组、write()方法
            ● HTMLElement接口定义了id,style,title,lang,dir和className属性。
            ● 其它的专有的HTML..相关接口也定义了专有的属性和方法,如HTMLInputElement定义了focus(),blur()...
            一个访问DOM接口的例子:
           
1 var  n  =  document.documentElement;   //  This is a Node object.
2 var  children  =  n.childNodes;        //  This is a NodeList object.
3 var  head  =  children.item( 0 );        //  Here is one way to use a NodeList.
4 var  body  =  children[ 1 ];             //  But this way is easier!
            另一个需要了解的是:DOM标准定义了接口,而不是类,所以它没有定义任何构造函数方法。如果想创建一个Text对象,把它插入文档,不能用如下代码:
            var t = new Text("this is a new text node");  // No such constructor
            取而代之的是,DOM在Document接口中定义了大量有用的工厂方法(factory method).因此,要为文档创建一个Text节点,可以使用以下代码:
            var t = document.createTextNode("this is a new text node");

    8.7 遍历文档
        DOM把一个HTML文档表示为Node对象的树,对于任何一个树形结构来说,最常用的事就是遍历树。
        →依次检查树的每个节点。如以下代码所示:
 1 img_405b18b4b6584ae338e0f6ecaf736533.gif img_1c53668bcee393edac0d7b3b3daff1ae.gif function  countTags(n)  {                         // n is a Node
 2    var numtags = 0;                            // Initialize the tag counter
 3img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    if (n.nodeType == 1 /**//*Node.ELEMENT_NODE*/)  // Check if n is an Element
 4         numtags++;                              // Increment the counter if so
 5    var children = n.childNodes;                // Now get all children of n
 6img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    for(var i=0; i < children.length; i++{    // Loop through the children
 7         numtags += countTags(children[i]);      // Recurse on each one
 8    }

 9    return numtags;                             // Return the total
10}


        除了childNodes属性,Node接口还定义了其它几个有用的属性,包括firstChild,lastChild,nextSibling,previousSibling.
        →获得DOM节点下所有的文本:
 
 1 img_405b18b4b6584ae338e0f6ecaf736533.gif img_1c53668bcee393edac0d7b3b3daff1ae.gif         function  getText(n)  {
 2            // Repeated string concatenation can be inefficient, so we collect
 3            // the value of all text nodes into an array, and then concatenate
 4            // the elements of that array all at once.
 5            var strings = [];
 6            getStrings(n, strings);
 7            return strings.join("");
 8
 9            // This recursive function finds all text nodes and appends
10            // their text to an array.
11img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif            function getStrings(n, strings) {
12img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif                if (n.nodeType == 3 /**//* Node.TEXT_NODE */)
13                    strings.push(n.data);
14img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif                else if (n.nodeType == 1 /**//* Node.ELEMENT_NODE */{
15                    // Note iteration with firstChild/nextSibling
16img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif                    for(var m = n.firstChild; m != null; m = m.nextSibling) {
17                        getStrings(m, strings);
18                    }

19                }

20            }

21        }
    
    8.8 在文档中查找元素
        ● getElementsByTagName()方法
            调用getElementsByTagName(param)方法,返回一个数组,该数组元素是文档中所有param元素。
            例如:
            var tables = document.getElementsByTagName("table");
            alert("This document contains " + tables.length + " tables");  // 文档中定义了多少个Table
            如果把特殊字符"*"传递给getElementsByTagName,它将返回文档中所有元素的列表。

            有时不想操作元素列表,而想操作文档中一个特定元素,如果对文档中结构有充分的了解,仍可以使用getElementsByTagName方法:
            var myParagraph = document.getElementsByTagName("p")[3];
            但这并不是最好的方法。最好的办法是使用getElementsById()方法、
        ● getElementById()方法
            getElementById方法不像getElementsByTagName返回一个数组列表,因为每个id属性值唯一,所以getElementById方法只返回一个元素。
            getElementById是一个很重要的方法,非常常见。
            以下通过getElementById方法获得表格中某个Cell的值。
           
1 var  tableOfContents  =  document.getElementById( " TOC " );
2 var  rows  =  tableOfContents.getElementsByTagName( " tr " );
3 var  numrows  =  rows.length;
        ● getElementsByName()方法
            与getElementById方法相似,它查询元素的name属性,而不是id属性。另外,一个文档中的name属性可能不唯一,所以getElementsByName方法返回的是元素的数组,而不是一个元素。
           
1 var  link  =  document.getElementsByName( " top " )[ 0 ];
2 //  Find all <input type="radio" name="shippingMethod"> elements
3 var  choices  =  document.getElementsByName( " shippingMethod " );

    8.9 修改文档内容
        DOM API的真正威力在于用Javascript动态修改文档的特性。
        →对元素的一个列表按字母排序
    
 1 < script >
 2 img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif function  sortkids(e)  {
 3     // This is the element whose children we are going to sort
 4     if (typeof e == "string") e = document.getElementById(e);
 5
 6     // Transfer the element (but not text node) children of e to a real array
 7     var kids = [];
 8     for(var x = e.firstChild; x != null; x = x.nextSibling)
 9img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif         if (x.nodeType == 1 /**//* Node.ELEMENT_NODE */) kids.push(x);
10
11     // Now sort the array based on the text content of each kid.
12     // Assume that each kid has only a single child and it is a Text node
13img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif     kids.sort(function(n, m) // This is the comparator function for sorting
14                   var s = n.firstChild.data; // text of node n
15                   var t = m.firstChild.data; // text of node m
16                   if (s < t) return -1;      // n comes before m
17                   else if (s > t) return 1;  // n comes after m
18                   else return 0;             // n and m are equal
19               }
);
20     for(var i = 0; i < kids.length; i++) e.appendChild(kids[i]);
21}

22 < / script>
23 < ul id = " list " >   <!--  This is the list we ' ll sort -->
24 <li>one<li>two<li>three<li>four <!-- items are not in alphabetical order -->
25 </ul>
26 <!-- this is the button that sorts the list -->
27 <button onclick="sortkids( ' list ' )">Sort list</button>

        →把文档内容转换为大小写
 1 img_405b18b4b6584ae338e0f6ecaf736533.gif img_1c53668bcee393edac0d7b3b3daff1ae.gif function  upcase(n)  {
 2img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    if (n.nodeType == 3 /**//*Node.TEXT_NODE*/{
 3        // If the node is a Text node, change its text to uppercase.
 4        n.data = n.data.toUpperCase();
 5    }

 6img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    else {
 7        // If the node is not a Text node, loop through its children
 8        // and recursively call this function on each child.
 9        var kids = n.childNodes;
10        for(var i = 0; i < kids.length; i++) upcase(kids[i]);
11    }

12}

13


        →把一个节点的父节点重定为<b>元素
 1 < script >
 2 img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif function  embolden(n)  {
 3    if (typeof n == "string") n = document.getElementById(n); // Lookup node
 4    var b = document.createElement("b"); // Create a new <b> element
 5    var parent = n.parentNode;           // Get the parent of the node
 6    parent.replaceChild(b, n);           // Replace the node with the <b> tag
 7    b.appendChild(n);                    // Make the node a child of the <b> element
 8}

 9 < / script>
10
11 <!--  A couple of sample paragraphs  -->
12 < p id = " p1 " > This  < i > is < / i> paragraph #1.< / p >
13 < p id = " p2 " > This  < i > is < / i> paragraph #2.< / p >
14 <!--  A button that invokes the embolden()  function  on the element named p1  -->
15 < button onclick = " embolden('p1'); " > Embolden < / button>
16
17



    8.10 修改节点属性
        可以调用element.setAttribute()方法来设置一个节点的属性,如:
       
1 var  headline  =  document.getElementById( " headline " );   //  Find named element
2 headline.setAttribute( " align " " center " );             //  Set align='center'
3 // 或者:headline.align = "center";  // Set alignment attribute.

    8.11 Document段
        DocumentFragment是一种特殊类型的节点,它自身不出现在文档中,只作为连续节点集合的临时容器,并允许将这些节点作为一个对象来操作。
        把一个DocumentFragment插入文档时,插入的不是DocumentFragment本身,而是它所持有的子节点。
       
1 img_405b18b4b6584ae338e0f6ecaf736533.gif img_1c53668bcee393edac0d7b3b3daff1ae.gif function  reverse(n)  {
2     // Create an empty DocumentFragment as a temporary container
3     var f = document.createDocumentFragment();
4     while(n.lastChild) f.appendChild(n.lastChild);
5     // Finally, move the children of f all at once back to n, all at once.
6     n.appendChild(f);
7}

    8.12 给文档添加内容
        Document.createElement()方法和Document.createTextNode()方法创建新的Element节点和Text节点。
        而方法Node.appendChild()、Node.insertBefore()和Node.replaceChild()可以用来将它们添加到一个文档。

    8.13 innerHTML属性
        该属性可以用来获得和设置结点中HTML文本。例如:
       
1 var  table  =  document.createElement( " table " );   //  Create the <table> element
2 table.border  =   1 ;                              //  Set an attribute
3 //  Add a Name|Type|Value header to the table
4 table.innerHTML  =   " <tr><th>Name</th><th>Type</th><th>Value</th></tr> " ;
目录
相关文章
|
8天前
|
JavaScript
JS 获取对象数据类型的键值对的键与值
JS 获取对象数据类型的键值对的键与值
|
11天前
|
JavaScript 算法
原生JS完成“一对一、一对多”矩形DIV碰撞检测、碰撞检查,通过计算接触面积(重叠覆盖面积)大小来判断接触对象DOM
原生JS完成“一对一、一对多”矩形DIV碰撞检测、碰撞检查,通过计算接触面积(重叠覆盖面积)大小来判断接触对象DOM
|
3天前
|
JavaScript
【Js】检查Date对象是否为Invalid Date
【Js】检查Date对象是否为Invalid Date
6 0
|
4天前
|
存储 JavaScript 前端开发
JavaScript的引用数据类型主要包括对象
【4月更文挑战第16天】JavaScript的引用数据类型主要包括对象
16 4
|
4天前
|
JavaScript 前端开发 应用服务中间件
node.js之第一天学习
node.js之第一天学习
|
8天前
|
Web App开发 缓存 JavaScript
|
8天前
|
JavaScript
js 字符串String转对象Object
该代码示例展示了如何将一个以逗号分隔的字符串(`&#39;1.2,2,3,4,5&#39;`)转换为对象数组。通过使用`split(&#39;,&#39;)`分割字符串并`map(parseFloat)`处理每个元素,将字符串转换成浮点数数组,最终得到一个对象数组,其类型为`object`。
|
16天前
|
存储 JavaScript 前端开发
在浏览器中存储数组和对象(js的问题)
在浏览器中存储数组和对象(js的问题)
|
存储 JavaScript 前端开发
|
移动开发 JavaScript 前端开发