20170609-DOM总结

DOM是针对HTML和XML文档的一个API。DOM描写了一个条理化的节点树,许可开发人员增加、移除和修正页面的某一部份。

节点条理

<!DOCTYPE html>
<html>
    <head>
        <title>sample page</title>
    </head>
    <body>
        <p>Hello World!</p>
    </body>
</html>

文档节点(Document node)是每一个文档的根节点(在浏览器中对应的是document),在这个例子中,文档节点有两个子节点,一个是<!DOCTYPE html>(DocumentTyep范例),另一个是<html>(Element范例)。文档元素是文档最外层的元素,文档中的其他一切元素都是包括在文档元素中。每一个文档只能有一个文档元素,在HTML页面中,文档元素一直是<html>元素。

Node范例

JavaScript中,一切节点范例都继续自Node范例,因而一切节点范例都同享着雷同的基础属性和要领

每一个节点都有一个nodeType属性,用于表明节点的范例.

  • 肯定节点范例

if (someNode.nodeType == Node.Element_NODE){
    alert("Node is an element");  // 表明该节点是一个HTML元素
}
或许
if (someNode.nodeType == 1){
    alert("Node is an element");  // 表明该节点是一个HTML元素
}

nodeName和nodeValue

  • 假如node是HTML标签,则nodeName的值就是元素的标署名,关于非文档节点,返回null

if (someNode.nodeType == 1){
    tagName = someNode.nodeName;
}
  • 关于文档节点(HTML标签)来讲, nodeValue返回null. 关于text, comment, 和 CDATA 节点来讲, nodeValue返回该节点的文本内容. 关于 attribute 节点来讲, 返回该属性的属性值.

节点之间的关联(node的一些属性):

  • node.childNodes

  • node.parentNode

  • node.previousSibling

  • node.nextSibling

  • node.firstChild

  • node.lastChild

操纵节点(node的一些要领)

  • node.appendChild():返回新增的节点,这个返回的节点是存在于DOM树中的节点,能够经由历程上面的属性接见DOM树中的其他节点

var returnNode = parentNode.appendChild(newNode);
  • insertBefore(newNode, baseNode): 同样会返回一个新节点,同上

  • replaceChild(newNode, replacedNode): 同样会返回一个新节点,同上

  • removeChild(node):会返回一个节点,该节点不存在于DOM树中

  • cloneNode:

// 实行深复制,即复制节点及其全部子树
var returnNode = someNode.cloneNode(true);

// 实行浅复制,只复制节点自身
var returnNode = someNode.cloneNode(false);

Document范例

JavaScript经由历程Document范例示意文档。在浏览器中,document对象是HTMLDocument(继续自Document范例)的一个实例,示意全部HTML页面。document对象是window对象的一个属性,因而能够作为全局对象来接见

文档子节点

Document节点(浏览器中是document)的子节点多是DocumentType(最多一个,比方<!DOCTYPE html>)、Element(最多一个比方 <html>)、ProcessingInstruction、Comment

  • document.documentElement 一直指向HTML页面中的文档元素(<html>)

  • document.body直接返回对<body>元素的援用

  • document.doctype会返回对<! DOCTYPE HTML>的援用

  • document.title返回文档题目的内容(只读)

  • document.childNodes会返回[<! DOCTYPE HTML>,html] (假如存在DOCTYPE的话)

文档信息:(能够猎取或许设置这些属性)

  • document.title

  • document.URL: 包括页面完全的URL(地址栏中的URL)

  • document.domain:

  • document.referrer: 链接到当前页面的谁人页面的URL

查找元素

  • document.getElementById()

  • document.getElementsByTagName():返回HTMLCollection对象

  • document.getElementsByName():返回带有给定name特征的一切元素,返回HTMLCollection对象

文档写入:

  • document.write():原样写入传入的字符串

  • document.writeln(): 在字符串的末端增加一个换行符

...
<body>
    <p>the current date and time is:
    <script>
        document.write("<strong>" + (new Date().toString() + "</strong>");
    </script>
</body.
  • 页面显现历程 中,经由历程上面的体式格局能够在指定位置输出内容

  • 这两个要领假如在页面加载完毕后被挪用,那末输出内容会重写全部页面

Element范例

要接见元素的标署名,能够运用nodeName属性或许tagName属性,这两个属性会返回雷同的值。注意在HTML中tagName会返回大写的标署名,在XML中返回值和代码中的标签一致。

<div id="myDiv"></div>

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

HTML元素

能够直接接见和修正的属性:

  • id: element.id

  • title: element.title

  • className: element.className

  • lang

  • dir: 笔墨方向

<div id="myDiv" class="bd" title="body text" lang="en" dir="ltr"></div>

var div = document.getElementById("myDiv");
alert(div.id);
alert(div.className);
alert(div.title);
alert(div.lang);
alert(div.dir);

获得特征: getAttribute

<div id="myDiv" class="bd" title="body text" lang="en" dir="ltr"></div>

var div = document.getElementById("myDiv");
alert(div.getAttribute("id"));
alert(div.getAttribute("class");
alert(div.getAttribute("title");
alert(div.getAttribute("lang");
alert(div.getAttribute("dir");

关于style、onclick这类特别的特征,getAttribute()只能返回响应代码的字符串,因而在经由历程JavaScript以编程的体式格局操纵DOM时,开发人员常常不运用getAttribute(),而是只运用对象的属性(div.id)

任何元素的一切特征,也都能够经由历程DOM元素自身的属性来接见。不过只要公认的特征才会以属性的情势增加到DOM对象中。 以下面的元素为例:

<div id="myDiv" align="left" my_special_attribute="hello!"></div>

由于id和align在html中是<div>的公认特征,因而在该元素的DOM对象中也将存在对应的属性。

alert(div.id); // "myDiv"
alert(div.my_special_attribute); // undefined
alert(div.align); //"left"

设置特征–setAttribute()

setAttribute()接收两个参数,要设置的特征名和值。假如特征已存在,则会替代已有的值,假如特征不存在,则会建立该属性并设置响应的值。

<div id="myDiv" class="bd" title="body text" lang="en" dir="ltr"></div>

var div=document.getElementById("myDiv");
div.setAttribute("id","someOtherId");

移除属性–removeAttribute()

<div id="myDiv" class="bd" title="body text" lang="en" dir="ltr"></div>

var div=document.getElementById("myDiv");
div.removeAttribute("id");

attributes属性:运用不轻易不常常运用,然则能够用来遍历元素特征

Element范例是运用attribute属性的唯一一个DOM节点范例。attribute属性中包括一个NamedNodeMap。元素的每一个特征都有一个Attr节点示意,每一个节点都保留在NamedNodeMap对象中。NamedNodeMap对象具有以下要领。

  • getNamedItem(name):返回nodeName属性即是name的节点

  • removeNamedItem(name): 移除nodeName属性即是name的节点

  • setNamedItem(node): 向列表中增加节点,以节点的nodeName属性为索引

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

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

var id = element.attributes["id"].nodeValue;
  • 运用不轻易不常常运用,然则能够用来遍历元素特征

function outputAttributes(element){
    var pairs = new Array(),
        attrName,
        attrValue,
        i,
        len;
    for(i=0; len=element.attributes.length; i<len; i++){
        attrName = element.attributes[i].nodeName;
        attrValue = element.attributes[i].nodeValue;
        pairs.push(attrName + " =\"" + attrValue + "\"");
.    }
    return pairs.join(' ');
}

建立元素

document.createElement()要领能够建立新元素,这个要领只接收一个参数,即要建立元素的标署名

var div = document.createElement("div");
div.id = "myDiv";
div.className = "box";
// 此时新元素还没有增加到文档树中,因而设置这些特征不会影响浏览器的显现
// 把新元素增加到文档树中:appendChild()、insertBefore()、replaceChild()
document.body.appendChild(div);

元素的子节点

假如想经由历程某个特定的标署名获得子节点或许子女节点,能够在元素上挪用getElementsByTagName()要领

Text范例

文本节点由Text范例示意,包括的是能够根据字面诠释的纯文本内容,然则不能包括HTML代码

主要的特性:

  • nodeType的值为3

  • nodeName为#text

  • nodeValue的值为节点包括的文本

  • parentNode是一个Element

  • 没有(不支持)子节点

有一些操纵节点中文本的要领:

  • appendData(text): 将text增加到末端

  • deleteData(offset, count): 从offset指定的位置最先,删除count个字符

  • insertData(offset, text):

  • replaceData(offset, count, text)

  • splitText(offset): 从offset指定位置将当前文本节点分红两个 文本节点

假如在一个包括两个或多个文本节点的父元素上挪用normalize()要领,则会将一切文本节点兼并成一个节点,效果节点的nodeValue即是将兼并前每一个文本节点的nodeValue值拼接起来的值。

DocumentFragment范例:

在一切的节点范例中,只要DocumentFragment在文档中没有对应的标记。DOM划定文档片断是一种“轻量级”的文档,能够包括和掌握节点,但不会像完全的文档那样占用分外的资本。

虽然不能把文档片断直接增加到文档中,然则能够将它作为一个堆栈来运用,即在内里保留未来可能会增加到文档中的节点。

建立文档片断的体式格局:document.createDocumentFragment()

var fragment = document.createDocumentFragment();
var ul = document.getElementById('myList');
var li = null;

//位ul增加三个li
for(var i=0; i<3; i++){
    li = document.createElement("li");
    li.innetText = "Item" + (i+1);
    fragment.appendChild(li);
}

ul.appendChild(fragment);

上面的例子是为ul元素增加3个列表项,假如逐一地增加列表项,将会致使浏览器频仍衬着新信息。为防止这个题目,能够运用frament,将一切列表项先增加到fragment中,末了将fragment增加到文档中。经由历程这类体式格局削减了浏览器的衬着次数。

DOM操纵手艺

动态剧本

  • 插进去外部文件

function loadScript(url){
    var script = document.createElement('script');
    script.type = "text/javascript";
    script.src = url;
    document.body.appendChild(script);
}
  • 行内体式格局

var script = document.createElement('script');
script.type = "text/javascript";
script.appendChild(document.creatTextNode('function sayHi(){alert('hi');}'));
document.body.appendChild(script);

动态款式

function loadStyles(url){
    var link = document.createElement("link");
    link.rel = "stylesheet";
    link.type = "text/css";
    link.href = url;
    var head = document.getElementsByTagName('head')[0];
    head.appendChild(link);
}

操纵表格

HTML DOM为<table>, <tbody>, <tr>元素增加了一些属性和要领,经由历程这些属性和要领,我们能够轻易的对表格举行操纵

运用NodeList

NodeList,NamedNodeMap和HTMLCollection都是动态的,每当文档构造发生变化时,它们都邑获得更新。

一般来讲,应当只管削减接见NodeList的次数,由于每次接见NodeList,都邑运转一次基于文档的查询,所以能够斟酌将从NodeList中掏出的值缓存起来。

总结

DOM操纵往往是JavaScript顺序中开支最大的部份,而因接见NodeList致使的题目为最多。NodeList对象都是“动态的”,这就意味着每次接见NodeList对象,都邑运转一次查询。有鉴于此,最好的方法就是只管削减DOM操纵。

    原文作者:jhhfft
    原文地址: https://segmentfault.com/a/1190000009717904
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞