码迷,mamicode.com
首页 > 编程语言 > 详细

《javascript高级程序设计》笔记(十)

时间:2014-10-12 18:36:38      阅读:301      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   color   io   os   使用   ar   java   

 

DOM

DOM(文档对象模型)是针对HTML和XML的一个API(应用程序编程接口)。DOM描绘了一个层次化的节点树,允许开发人员增加、删除、修改页面的某一部分。

一、节点层次

文档节点是每个文档的根节点。每个文档只能有一个文档元素,HTML页面的文档元素始终是<html>元素,XML里没有预定义元素。

HTML元素通过元素节点表示,特性(attribute)通过特性节点表示,文档类型通过文档类型节点表示,注释通过注释节点表示。总共有12种节点类型,都继承自一个基类型。

1.Node类型

DOM 1级定义了一个Node接口,该接口将由DOM中的所有节点类型实现。除了IE都能访问这个类型。

每一个节点都有一个nodeType属性,用于表明节点的类型。

  • Node.ELEMENT_NODE                              (1)  
  • Node.ATTRIBUTE_NODE                           (2)  
  • Node.TEXT_NODE                                    (3) //<![CDATA[ ]]>中括着的纯文本,它没有子节点
  • Node.CDATA_SECTION_NODE                   (4) //子节点一定为TextNode
  • Node.ENTITY_REFERENCE_NODE              (5)  
  • Node.ENTITY_NODE                                 (6) //DTD中的实体定义<!ENTITY foo “foo”>,无子节点
  • Node.PROCESSING_INSTRUCTION_NODE  (7) //PI,无子节点
  • Node.COMMENT_NODE                             (8)  
  • Node.DOCUMENT_NODE                           (9) //最外层的Root element,包括所有其它节点
  • Node.DOCUMENT_TYPE_NODE                  (10) //DTD,<!DOCTYPE………..>
  • Node.DOCUMENT_FRAGMENT_NODE         (11)  
  • Node.NOTATION_NODE                            (12) //DTD中的Nation定义
if(someNode.nodeTyoe == Node.ELEMENT_NODE){   //IE中无效  IE没有公开Node类型的构造函数
    alert("Node is an element.");
}

if(someNode.nodeTyoe == 1){   //适用于所有浏览器
    alert("Node is an element.");
}

最常用的是元素文本节点。

①nodeName和nodeValue

对元素节点,nodeName保存的始终是元素的标签名,nodeValue始终是null。

 

②节点关系

每一个节点都有一个childNodes属性,保存着一个NodeList对象。用于保存一组有序的节点,可以通过位置来访问节点。

var firstChild = someNode.childNode[0];   //方括号
var secondChild = someNode.item(1);      //item()方法
var count = someNode.childNode.length;

 

function convertToArray(nodes) {将NodeList转换为数组
    var array = null;
    try {
         array = Array.prototype.slice.call(node, 0);  //非IE浏览器
    }
    catch (ex) {  //IE浏览器
        array = new Array() ;
        for (var i = 0, len = nodes.length;i<len;i++){
              array.push(node[i]);     
        }
    }

        return array;
    }

 

每个节点都有parentNode属性,指向文档树的父节点。

previousSiblingnextSibling属性可以访问同一列表的其他节点。

父节点与子节点:firstChildlastChild。

hasChildNodes()方法:节点包含一个或多个子节点时返回true。

ownerDocument属性:指向表示整个文档的文档节点。

 

③操作节点

appendChild() :向childNodes列表末尾添加一个节点,返回新增节点。

如果传入的节点已经是文档的一部分,那就将该节点从原来的位置转移到新位置。如果在调用appendChild()时传入了父节点的第一个节点,该节点会变成父节点的最后一个节点。

 

insertBefore() :接受两个参数:要插入的节点和作为参照的节点。插入节点后,被插入的节点会变成参照节点的前一个同胞节点,同时被方法返回。

//插入后成为最后一个节点
returnNode = someNode.insertBefore(newNode, null);
alert(newNode == someNode.lastChild);   //true

 

replaceChild() :接受两个参数:要插入的节点和要替换的节点。要替换的节点由这个方法返回并从文档树里移除。

 

removeChild() :移除节点。被移除的节点成为返回值。

 

④其他方法

cloneNde() :创建调用这个方法的节点的一个完全相同的副本,接受一个布尔值参数表示是否进行深复制。

                      深复制:复制节点及其整个子节点树。  浅复制:只复制节点本身。

不会复制添加到DOM节点的javascript属性,如事件处理程序等,只复制特性、明确指定下也复制节点。其他一切都不复制。

IE会复制事件处理程序,所以复制前最好移除事件处理程序。

2.Document类型

document对象是HTMLDocument(继承自Document类型)的一个实例,表示整个HTML页面。Document节点特性:

nodeType的值为9;

nodeName的值为"#document";

nodeValue的值为null;

parentNode的值为null;

ownerDocument的值为null;

其子节点可能是一个DocumentType(最多一个)、Element(最多一个)、ProcessingInstruction或Comment。

最常用是作为HTMLDocument实例的document对象。通过这个文档对象,不仅可以取得与页面相关的信息,还能操作页面的外观和底层结构。

 

①文档的子节点

Document节点的子节点可以是Document、Element、ProcessingInstruction、或Comment。

访问其子节点       documentElement属性始终指向HTML页面的<html>元素。     通过childNodes列表访问文档元素。

 

document.body  取得对<body>的引用。

 

Document另一个可能的子节点是DocumentType,但不同浏览器对其支持差别很大。

var doctype = document.doctype;  //取得对<!DOCTYPE>的引用

 

②文档信息

title属性:包含<title>元素的文本,可以取得、修改当前页面的标题并反映在浏览器的标题,不会改变<title>元素。

URL属性:包含页面完整的URL,domain属性只包含页面的域名,referrer属性保存着链接到当前页面的那个页面的URL。

 

只有domain可以设置,不能将其设置为URL不含的域。当页面中包含来自其他子域的框架或内嵌框架时设置document.domain非常方便。

如果域名一开始是松散的,不能讲它再设置为绷紧的。

 

//假设页面来自p2p.worx.com域

document.domain = "wrox.com";       //loose 成功

document.domain = "p2p.wrox.com";   //tight 失败

 

③查找元素

getElementById:接受一个要取得的元素的ID,ID要与元素的id特性严格匹配(IE8及之前不分大小写)。如果页面有多个元素I相同,之返回第一次出现的元素。IE7及之前的版本,如果第一次出现的是与ID相同的Name元素也会返回。

 

getENagelementByTagNage():接收元素的标签名,返回零个或多个元素的NodeList。在HTML文档会返回一个HTMLCollection对象,可以用方括号语法或item()方法访问里面的项。

                                                   要取得文档的所有元素可以传入"*"。——第一项是<html>,第二项是<head>,IE将注释实现为元素,也会返回注释节点。

 

getElementByName() :返回带有给定name特性的所有元素。最常用是取得单选按钮。

 

④特殊集合

document.anchors    所有带name属性的<a>元素

document.forms       所有的<form>元素

document.images     所有的<img>元素

document.links         所有带href特性的<a>元素          

 

⑤DOM一致性检测

DOM1级——hasFeature()   接收两个参数:检测的DOM功能的名称和版本号。

write() :原样写入一个字符串参数

 

writeln() :在字符串末尾加上换行符

注意</script>要加上转义字符\

 

open()  close()  打开和关闭网页的输出流

 

⑥文档写入

 

3.Element类型

Element类型用于表现HTML或XML元素,提供对元素标签名子节点特性的访问。

nodeType的值为1

nodeName的值为元素的标签名

nodeValue的值为null

parentNode可能是Document或Element

 

nodeName属性与tagName属性 都返回元素的标签名

HTML中标签名始终以全部大写表示,XML里标签名与源代码一致。

if (element.tagName.toLowerCase() == "div"){
   //执行操作
}

 

①HTML元素

所有HTML元素都由HTMLElement类型表示,它继承自Element并添加了一些属性:id title lang dir className(与元素的class特性对应,class是ECMAScript的保留字)

这些信息可以通过js代码取得或修改

<div id="myDiv" class="bd" title="Body text" lang="en" dir="ltr">Some text</div>
 alert(div.className);  //"bd"
 div.className = "ft";

对id或lang的修改对用户是不可见的(没有基于它们的值设置的CSS样式),对title的修改只会在鼠标移动到这个元素上时才显示,对dir修改会立即影响文本的对其方式。修改className时如果新类关联了与此前不同的CSS,会立即应用新样式。

 

②取得特性

操作特性的DOM方法:getAttribute()、setAttribute()、removeAttribute

var dir = document.getelementByID("myDiv");
alert(div.getAttribute("class"));   //"bd"

想要得到class的特性值,要传入class   className只有在通过对象属性访问特性时才用

getAttribute()可以获取自定义特性。

任何元素的所有特性都可以通过 DOM元素本身的属性来访问。只有非自定义的特性才会以属性的形式添加到DOM对象中,但IE会为自定义特性创建属性。

<div id="myDiv" class="bd" my_special_attribute="hello!">Some text</div>
alert(div. my_special_attribute);   //undefined  (IE除外)

 

属性的值与通过getAttribute()返回的值并不一致

style——用于通过CSS为元素指定样式,getAttribute访问时返回style特性值中包含的是CSS文本,通过属性来访问会返回一个对象。

onclick——getAttribute访问会返回相应代码的字符串,访问onclick属性会返回一个javascript函数。  因为onclick与其他事件处理程序属性本身就应该被赋予函数值。

 

开发人员经常不使用getAttribute(),只使用对象的属性,只有在取得自定义特性值的情况下才会使用getAttribute()。

 

③设置特性

setAttribute()   接收两个参数:要设置的特性名和值。

可以操作HTML特性和自定义特性,特性名都转换成小写

所有特性都是属性,但给DOM元素添加一个自定义的属性,该属性不会自动成为元素的特性。

div.myColor = "red";
alert(div.getAttribute("div.myColor ")); //undefined (IE除外)

IE7和以前的版本setAttribute() 设置class、style和事件处理程序会没效果。

 

removeAttribute()  彻底删除元素的特性,IE6及以前版本不支持。

 

④attributes属性

Element类型是使用attributes属性的唯一一个DOM节点类型。

attributes属性包含一个NamedNodeMap,元素的每一个特性都由一个Attr节点表示,每个节点都保存在NamedNodeMap对象。

 

getNamedItem(name):返回nodeName属性等于name的节点。

removeNameItem(name):从列表中移除nodeName属性等于name的节点。

setNameItem(node):向列表中添加节点,以节点的nodeName属性为索引。

item(pos):返回位于数字pos位置处的节点。

 

//获取元素的id特性
var id = element.attributes.getNamedItem("id").nodeValue;
var id = element.attributes["id"].nodeValue;
//设置新值
element.attributes["id"].nodeValue = "someOtherId";

 

removeNameItem()方法与在元素调用removeAttribute()一样,removeNameItem返回被删除特性的Attr节点。

setNameItem不常用,为元素添加一个特性,需要为它传入一个特性节点。

 

attributes方法不方便,更多使用getAttribute()、setAttribute()。

 

要遍历元素特性,attributes属性可以用。在将DOM结构序列转换为XML或HTML字符串时,多数会涉及遍历元素特性。

 

⑤创建元素

docmun.createElement()可以创建新元素,接收一个参数:元素的标签名。元素添加到文档树,浏览器就会立即呈现该元素。

通过在createElement()指定完整的HTML标记可以解决IE7及之前版本的动态创建元素的问题。

 

⑥元素的子节点

//非IE中ul元素里有7个元素
<ul id="myList">
      <li>Item 1</li>
      <li>Item 2</li>
      <li>Item 3</li>
</ul>

//ul元素有3个元素
<ul id="myList"><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>

 

通过childNode遍历子节点要检查nodeType属性

for  (i=0, len=element.childNodes.length; i < len; i++) {
      if  (element.childNodes[i].nodeType ==1){
           //操作
      } 
}

 

4.Text类型

可以包含转义后的HTML字符,但不能包含HTML代码。

nodeType的值为3。

nodeValue属性与data属性的值相同

方法:

appendData(text)     deleteData(offset, count)    insertData(offerset, text)    replaceData(offerset, count, text)    splitText(offerset)     substringData(offerset,  count)

length属性保存字符数目。

默认每个可以包含内容的元素最多只有一个文本节点,而且必须有内容。

 

在修改文本节点时,字符串会经过HTML(XML)编码

div.firstChild.nodeValue = "Some <strong>other</strong> message";
                     //输出 Some &lt;strong&gt;other&lt;/strong&gt; message

 

①创建文本节点

 document.createTextNode()   接收一个参数:要插入节点的代码,按照HTML或XML格式编码。

如果两个文本节点是相邻的同胞节点,文本会连起来,中间不会有空格。

 

②规范化文本节点

normallize() :在含两个或以上文本节点的父节点调用,将所有文本节点合并成一个节点,结果等于每个节点的值连接起来。

浏览器解析文档不会创建相邻的文本节点,只会在执行DOM操作时出现。

 

③分隔文本节点

splitText()  :接收一个参数:分隔的位置,返回一个新文本节点。

原来的文本节点包含从开始位置到指定位置之前的内容,新文本节点包含剩下的内容。

 

5.Comment类型

nodeValue的值是注释的内容。

与Text类继承自相同的基类,拥有除splitText()之外的所有字符串操作方法。

可以通过父节点来访问。

 

6.CDATASection类型

只针对基于XML的文档,表示CDATA区域,拥有除了splitText()以外所有字符串操作方法。

 

7.DocumentTyple类型

只有Firefox、Safari、Opera支持。包含文档的doctype的所有信息。

 

8.DocumentFragment类型

唯一在文档中没有对应的标记的节点。

不能添加到文档,但可以作为仓库使用,保存将来可能添加到文档的节点。

 

逐个添加列表项会导致浏览器反复渲染新信息,可以使用一个文档片段保存新建的列表项,一次性添加到文档。

            var fragment = document.createDocumentFragment();
            var ul = document.getElementById("myList");
            var li = null;
            
            for (var i=0; i < 3; i++){
                li = document.createElement("li");
                li.appendChild(document.createTextNode("Item " + (i+1)));
                fragment.appendChild(li);
            }
            
            ul.appendChild(fragment);  

 

9.Attr类型

 元素的特性在DOM用Attr类型来表示,特性就是存在于元素的attributes属性中的节点。有name、value、specified属性,specified是一个布尔值,区别特性是在代码中指定的还是默认的。

一般使用getAttribute()、setAttribute(),很少引用特性节点。

二、DOM操作技术

1.动态脚本

在页面加载时不存在,但将来某一时刻通过修改DOM动态添加的脚本。

function loadScript(url){
     script = document.createElement("script");
     script.type = "text/javascript";
     script.src = url;
     document.body.appendChild(script);
}

 

行内方式

        function loadScriptString(code){
            var script = document.createElement("script");
            script.type = "text/javascript";
            try {    //IE将<script>视为特殊元素,不允许DOM访问其子节点
                script.appendChild(document.createTextNode(code));
            } catch (ex){
                script.text = code;  //用text属性指定代码
            }
            document.body.appendChild(script);
        }
    
        function addScript(){
            loadScriptString("function sayHi(){alert(‘hi‘);}");
            sayHi();
        }

 这种方法回在全局作用域中执行,当脚本执行后可立即使用,与在全局作用域把字符串传递给eval()一样。

 

2.动态样式

需要将<link>元素添加到<head>元素才能保证在所有浏览器的行为一致。

        function loadStyleString(css){
            var style = document.createElement("style");
            style.type = "text/css";
            try{
                //IE不允许访问<style>的子节点
                style.appendChild(document.createTextNode(css));   
            } catch (ex){
                //访问元素的 styleSheet 属性的cssText属性
                style.styleSheet.cssText = css;
            }
            var head = document.getElementsByTagName("head")[0];
            head.appendChild(style);
        }

在重用同一个<style>元素并在此设置这个属性或将cssText设置为空字符可能导致浏览器崩溃。

 

3.操作表格

使用DOM的属性和方法可以减少创建表格的代码数量。

 

4.使用NodeList

所有NodeList对象都是在访问DOM文档时实时运行的查询。

 

要迭代NodeList,最好使用length属性初始化第二个变量。

var divs = document.getElementByID("div"),
      i,
len, div;
for (i=0, i < divs.length; i++){//无限循环
//更正for (i=0, len < divs.length; i++){
div
= document.createElement("div"); document.dody.appendChild(div); }

 

《javascript高级程序设计》笔记(十)

标签:des   style   blog   color   io   os   使用   ar   java   

原文地址:http://www.cnblogs.com/surahe/p/4008877.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!