zoukankan      html  css  js  c++  java
  • DOM

    10.1 节点层次

    DOM可以将任何HTML或XML文档描绘成一个由多层节点构成的结构。以下面的HTML为例:

    <html>
            <head>
                <title>Sample Page</title>
            </head>
            <body>
                <p>Hello World!</p>
            </body>
    </html>

    文档节点是每个文档的根节点。在上述例子中,文档节点只有一个子节点,即<html>,我们称之为文档节点。

    文档节点是文档的最外层元素,文档中的其他所有元素都包含在文档元素中。每个文档只能有一个文档元素。

    10.1.1 Node类型

    每个节点都有一个nodeType属性,用于表明节点的类型。节点类型由在Node类型中定义的下列12个数值常量来表示,任何节点类型必居其一:

    Node.ELEMENT_NODE(1);

    Node.ATTRIBUTE_NODE(2);

    Node.TEXT_NODE(3);

    Node.CDATA_SECTION_NODE(4);

    Node.ENTITY_REFERENCE_NODE(5);

    Node.ENTITY_NODE(6);

    Node.PROCESSING_INSTRUCTION_NODE(7);

    Node.COMMENY_NODE(8);

    Node.DOCUMENT_NODE(9);

    Node.DOCUMENT_TYPE_NODE(10);

    Node.DOCUMENT_FRAGMENT_NODE(11);

    Node.NOTATION_NODE(12);

    为了确保浏览器兼容,最好将nodeType属性与数字值进行比较

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

    1、nodeName和nodeValue属性

    要了解节点的具体信息,可以使用nodeName和nodeValue这两个属性。这两个属性的值完全取决于节点的类型。在使用这两个值以前,最好是先检测下节点的类型

    如果节点是一个元素,nodeName中保存的始终都是元素的标签名,而nodeValue的值始终是null。

    2、节点关系

    文档中所有的节点之间都存在这样或那样的关系。

    每个节点都有一个childNodes属性,其中保存着一个NodeList对象。NodeList是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点。请注意,虽然可以通过方括号语法来访问NodeList的值,而且这个对象也有length属性,但是它并不是Array的实例。NodeList对象的独特之处在于,它实际上是基于DOM结构动态执行查询的结果,因此DOM结构的变化能够自动反映在NodeList对象中。我们常说,NodeList是有生命、有呼吸的对象,而不是在我们第一次访问它们的某个瞬间摆着的一张快照。

    访问保存在NodeList中的节点——可以通过方括号,也可以使用item()方法

    var firstChild = someNode.childNodes[0];
    var secondChild = someNode.childNodes.item(1);
    var count = someNode.childNodes.length;

    节点间关系图

    hasChildNodes()是一个非常有用的方法。

    3、操作节点

    (1)appendChild()用于项childNodes列表的末尾添加一个节点。更新完成后,appendChild()返回新增的节点。

    var returnedNode = someNode.appendChild(newNode);
    alert(returnedNode == newNode);          //true
    alert(someNode.lastChild == newNode);    //true

    注意:如果传入到appendChild()中的节点已经是文档的一部分了,那结果就是将该节点从原来的位置转移到新的位置。即使可以将DOM树看作是由一系列指针连接起来的,但任何DOM节点也不能同时出现在文档的多个位置上。因此,如果在调用appendChild()时传入了父节点的第一个子节点,那么该节点就会成为父节点的最后一个子节点,

    var returnedNode = someNode.appendChild(someNode.firstChild);
    alert(returnedNode == someNode.firstChild);   //false;
    alert(returnedNode == someNode.lastChild);   //true;

    (2)insertBefore()方法,接收两个参数:要插入的节点和作为参照的节点。插入节点后,被插入的节点会编程参照节点的前一个同袍节点,同时被方法返回。如果参照节点是null,则insertBefore()与appendChild()执行相同的操作。

    //插入后成为最后一个节点
    returnedNode = someNode.insertBefore(newNode,null);
    alert(newNode == someNode.lastChild);   //true
    
    //插入后成为第一个节点
    returnedNode = someNode.insertBefore(newNode,someNode.firstChild);
    alert(returnedNode == newNode);  //true
    alert(newNode == some.firstChild); //true
    
    //插入到最后一个子节点的前面
    
    returnedNode = someNode.insertBefore(newNode,someNode.lastChild);
    alert(newNode == some.childNodes[someNode.childNodes.length-2]); //true

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

    //替换第一个子节点
    var returnedNode = someNode.replaceChild(newNode,someNode.firstChild);
    
    //替换最后一个节点
    var returnedNode = someNode.replaceChild(newNode,someNode.lastChild);

    (4)removeChild()移除某个节点。接受一个参数,即要移除的节点

    //移除第一个节点
    var
    returnedNode = someNode.removeChild(someNode.firstChild); //移除最后一个节点 var returnedNode = someNode.removeChild(someNode.lastChild);

    (5)cloneNode()用于创建调用这个方法的节点的一个完全相同的副本。cloneNode()方法接受一个布尔值参数,表示是否执行深复制。在参数为true的情况下,执行深复制,即复制节点及整个子节点树;在参数为false的情况下,执行浅复制,即只复制节点本身。复制后的节点副本属于文档所有,但并没有为它指定父节点。除非通过appendChild()、insertBefore()或replaceChild()将它添加到文档中。

    10.1.2 Document类型

    JavaScript通过Document类型表示文档。在浏览器中,document对象是HTMLDocument(继承自Document类型)的一个实例,表示整个HTML页面。而且,document对象是window对象的一个属性,因此可以将其作为全局对象来访问。

    Document节点具有下列特征:

    nodeType的值是9;

    nodeName的值为“#document”;

    nodeValue的值是null;

    parentNode的值为null;

    ownerDocument的值为null;

    (1)文档的子节点

    有两个内置的访问Document节点的子节点快捷方式。第一个就是documentElement属性,该属性始终指向HTML页面中的<html>元素。另一个就是通过childNodes列表访问文档元素,但通过documentElement属性更快捷、更直接。

    <html>
        <body>
        </body>
    </html>

    这个页面在经过浏览器解析后,其文档中只包含一个子节点,即<html>元素。可以通过documentElement或childNodes列表来访问这个元素

    var html = document.documentElement; //取得对<html>的引用
    alert(html === document.childNodes[0]);  //true
    alert(html === document.firstChild);         //true

    document对象还有一个body属性,直接指向<body>元素。

    var body = document.body;

    Document的另一个可能的子节点是DocumentType。通常将<!DOCTYPE>标签看成一个与文档其他部分不同的实体,可以通过doctype属性来访问它的信息

    var doctype = document.doctype;

    由于浏览器对document.doctype的支持不一致,因此这个属性的用处很有限。

    (2)文档信息

     第一个属性是title,包含着<title>元素中的文本——显示在浏览器窗口的标题栏或标签页上。通过这个属性可以取得当前页面的标题,也可以修改当前页面的标题并反映在浏览器的标题栏或标签页上。通过这个属性可以取得当前页面的标题,也可以修改当前页面的标题并反映在浏览器的标题栏中。修改title属性的值不会改变<title>元素。

    //取得文档标题
    var originalTitle = document.title;
    
    //设置文档标题
    document.title = "New page title";

    与网页请求有关的3个属性:URL、domain和referrer。URL属性中包含页面完整的URL(即地址栏中显示的URL),domain属性中只包含页面的域名,而referrer属性中则保存着链接到当前页面的那个页面的URL。在没有来源页面的情况下,referrer属性中可能会包含空字符串。所有这些信息都存在于请求的HTTP头部。

    //取得完整的URL
    var url = document.url;
    //取得域名
    var domain = document.domain;
    //取得来源页面的URL
    var url = document.referrer;

    这三个属性,只有domain是可以设置的。但由于安全考虑,也并非可以给domain设置任何值。如果URL中包含一个子域名,例如p2p.wrox.com,那么就只能将domain设置为“wrox.com”.不能将这个属性设置为URL中不包含的域

    (3)查找元素

    1、getElementById(),接收一个参数:要取得的元素的ID。

    注意:IE8以及低版本不区分ID的大小写,因此“myDiv”和“mydiv”会被当做相同的元素ID。

    如果页面中多个元素的ID值相同,getElementById()只返回文档中第一次出现的元素。IE7及较低版本还为此方法添加了一个有意思的“怪癖”:name特性与给定ID匹配的表单元素也会被该方法返回。如果有哪个表单元素的name特性等于指定的ID,而且该元素在文档中位于带有给定ID的冤死前面,那么IE就会返回那个表单元素。

    <input type="text" name="myElement" value="Text field">
    <div id="myElement">A div</div>

    基于上述代码,在IE7中调用document。getElementById("myElement"),结果会返回<input>元素;而在其他浏览器中,都会返回对<div>元素的引用。

    2、getElementsByTagName();接收一个参数:即要取得元素的标签名,而返回的是包含零或多个元素的NodeList。

    var images = document.getElementsByTagName("img");

    与NodeList对象类似,可以使用方括号语法或者item()方法来访问HTMLCollection对象中的项。而这个对象中元素的数量则可以通过其length属性取得

    alert(images.length);  //输出图像的数量
    alert(images[0].src);   //输出第一个图像元素的src特性
    alert(images.item(0).src);   //输出第一个图像元素的src特性

    HTMLCollection对象还有一个方法,叫做namedItem(),使用这个方法可以通过元素的name特性取得集合中的项。

    <img src="myimage.gif" name="myImage" >
    可以通过以下方式从images变量中取得这个<img>元素
    var myImage = images.namedItem("myImage");
    对命名的项也可以使用方括号语法来访问
    var myImage = images.namedItem{["myImage"];

    可以向getElementsByTagName()中传入“*”。在JavaScript及css中,星号(“*”)通常表示全部。

    var allElements = document.getElementsByTagName("*");包含整个页面的所有元素——按照它们出现的先后顺序。

    3、getElementsByName()这个方法会返回带有给定name特性的所有元素

    4、特殊集合

    document.anchors  包含文档中所有带name特性的<a>元素

    document.forms 包含文档中所有的<form>元素,与document.getElementsByTagName("form")得到的结果相同

    document.images 包含文档中所有的<img>元素,与document.getElementsByTagName("img")得到的结果相同

    document.links 包含文档中所有带href特性的<a>元素

    10.1.3 Element类型

    Element类型是Web编程中最常见的类型了。Element类型用于表现XML或HTML元素,提供对元素标签名、子节点及特性的访问。

    要访问元素的标签名,可以使用nodeName属性,也可以使用tagName属性;这两个属性会返回相同的值。

    <div id="myDiv"></div>
    
    var div = document.getElementById("myDiv");
    alert(div.tagName);  //"DIV"
    alert(div.tagName == div.nodeName);  //true;

    1、取得特性

    每个元素都有一个或多个特性,这些特性的用途是给出相应元素或其内容的附加信息。操作特性的DOM方法有三个:getAttribute()、setAttribute()、removeAttribute()

    var div = document.getElementById("myDiv");
    alert(div.getAttribute("id"));  //"myDiv"
    alert(div.getAttribute("class"); // "bd"

    2、设置特性

    与getAttribute()对应的方法是setAttribute()。这个方法接受两个参数:要设置的特性名和值。

    div.setAttribute("id","someOtherId");

    3、删除特性

    removeAttribute()这个方法用于彻底删除元素的特性,调用这个方法不仅会清楚特性的值,而且会从元素中完全删除特性

    div.removeAttribute("class");

    4、attributes属性

    var id = element.attributes.getNamedItem("id").nodeValue;
    var id = element.attributes["id"].nodeValue;

    用处:

    如果想要遍历元素的特性,attributes属性可以使用

    for(var i = 0;i < element.attributes.length;i++){
      attrName = element.attributes[i].nodeName;
      attrValue = element.attributes[i].nodeValue;
    }

    5、创建元素

    document.createElement()可以创建新元素

    var div = document.createElement("div");

    6、元素的子节点

    使用children、firstElementChild、lastElementChild、nextElementSlibling、parentNode可以取得element元素,避免其他类型节点

    10.1.4 文本节点

    文本节点有text类型表示,包含的是可以照字面解释的纯文本内容。

    1、创建文本节点

    document.createTextNode()创建新文本节点,这个方法接受一个参数,要插入节点中的文本

    var element = document.createTextNode("<strong>Hello</strong>world!");

    var element = document.createTextNode("Hello world!");

    2、规范化文本节点

    DOM文档中出现相邻文本节点的情况也不在少数,有一个将相邻文本节点合并的方法,normalize()。如果在一个包含两个或多个文本节点的父元素上调用normalize()方法,则会将所有文本节点合并成一个节点。

    var element = document.createElement("div");
    element.className = "message";
    
    var textNode = document.createTextNode("Hello World");
    element.appendChild(textNode);
    
    var anotherTextNode = document.createTextNode("xiaolu");
    element.appendChild(anotherTextNode);
    
    document.body.appendChild(element):
    
    element.childNodes.length; //2
    
    element.normalize();
    element.childNodes.length; //1

    3、分割文本节点

    var element = document.createElement("div");
    element.className = "message";
    
    var textNode = document.createTextNode("Hello World");
    element.appendChild(textNode);
    
    var anotherTextNode = document.createTextNode("xiaolu");
    element.appendChild(anotherTextNode);
    
    document.body.appendChild(element):
    
    var newNode = element.firstChild.splitText(5);
    element.firstChild.nodeValue = "Hello";
    newNode.nodeValue;  //" World";
    
    element.childNodes.length; //2

    10.1.8 DocumentFragment类型

    DOM规定文档片段是一种“轻量级”的文档,可以包含和控制节点,但不会像完整的文档那样占用额外的资源。

    要创建文档片段,可以使用document.createDocumentFragment();方法

    var fragment = document.createDocumentFragment();
    
    var ul = document.createElement("div");
    var li = null;
    
    for(var i = 0;i < 3;i++){
    li = document.createElement("li");
    li.appendChild(document.createTextNode("Item "+(i+1)));
    frament.appendChild(li);
    }
    
    ul.appendChild(fragment);
  • 相关阅读:
    [C]%p和%02x含义
    [python]特殊输入格式(输入中包含空格逗号等)
    《python编程从入门到实践》用户输入和while循环
    [ C ]根据年月日判断周几(基姆拉尔森计算公式)
    《python编程从入门到实践》字典
    《python编程从入门到实践》if语句
    记一次页面乱码问题的解决
    apache配置健康检查
    nginx 配置代理对象的host
    nginx配置http负载均衡
  • 原文地址:https://www.cnblogs.com/deerfig/p/7341423.html
Copyright © 2011-2022 走看看