JS总结篇--[总结]JS操纵DOM经常使用API详解

文本整顿了javascript操纵DOM的一些经常运用的api,依据其作用整顿成为建立,修正,查询等多种范例的api,重要用于温习基础知识,加深对原生js的熟悉。

基础观点

在解说操纵DOM的api之前,起首我们来温习一下一些基础观点,这些观点是控制api的症结,必需明白它们。

Node范例

DOM1级定义了一个Node接口,该接口由DOM中一切节点范例完成。这个Node接口在JS中是作为Node范例完成的。在IE9以下版本无法接见到这个范例,JS中一切节点都继续自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.COMMENT_NODE:8
Node.DOCUMENT_NODE:9
Node.DOCUMENT_TYPE_NODE:10
Node.DOCUMENT_FRAGMENT_NODE:11
Node.NOTATION_NODE:12

假定我们要推断一个Node是不是是元素,我们能够如许推断:

if(someNode.nodeType == 1){
    console.log("Node is a element");
}

开发人员最经常运用的就是元素和文本节点。

这些Node范例中,我们最经常运用的就是elementtextattributecommentdocumentdocument_fragment这几种范例。
我们简朴来引见一下这几种范例:

Element范例

Element供应了对元素标署名,子节点和特性的接见,我们经常运用HTML元素比方div,span,a等标签就是element中的一种。Element有下面几条特性:
(1)nodeType为1
(2)nodeName为元素标署名,tagName也是返回标署名
(3)nodeValue为null
(4)parentNode多是Document或Element
(5)子节点多是Element,Text,Comment,Processing_Instruction,CDATASection或EntityReference

Text范例

Text示意文本节点,它包含的是纯文本内容,不能包含html代码,但能够包含转义后的html代码。Text有下面的特性:
(1)nodeType为3
(2)nodeName为#text
(3)nodeValue为文本内容
(4)parentNode是一个Element
(5)没有子节点

Attr范例

Attr范例示意元素的特性,相当于元素的attributes属性中的节点,它有下面的特性:
(1)nodeType值为2
(2)nodeName是特性的称号
(3)nodeValue是特性的值
(4)parentNode为null

Comment范例

Comment示意HTML文档中的解释,它有下面的几种特性:
(1)nodeType为8
(2)nodeName为#comment
(3)nodeValue为解释的内容
(4)parentNode多是Document或Element
(5)没有子节点

Document

Document示意文档,在浏览器中,document对象是HTMLDocument的一个实例,示意全部页面,它同时也是window对象的一个属性。Document有下面的特性:
(1)nodeType为9
(2)nodeName为#document
(3)nodeValue为null
(4)parentNode为null
(5)子节点多是一个DocumentType或Element

DocumentFragment范例

DocumentFragment是一切节点中唯一一个没有对应标记的范例,它示意一种轻量级的文档,能够看成一个临时的堆栈用来保存能够会增加到文档中的节点。DocumentFragment有下面的特性:
(1)nodeType为11
(2)nodeName为#document-fragment
(3)nodeValue为null
(4)parentNode为null

我们简朴地引见了几种罕见的Node范例,要记着,HTML中的节点并不只是包含元素节点,它还包含文本节点,解释节点等等。在这里我们只是简朴地说清楚明了几种罕见的节点,想要进一步进修的同砚能够查找一下相干材料。

节点建立型api

在这里,我将经常运用的DOM操纵api举行分类,起首要引见的是建立型的api。这一范例的api,简而言之就是用来建立节点的。

createElement

createElement经由历程传入指定的一个标署名来建立一个元素,假如传入的标署名是一个未知的,则会建立一个自定义的标签,注重:IE8以下浏览器不支持自定义标签。
运用以下:

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

运用createElement要注重:经由历程createElement建立的元素并不属于html文档,它只是建立出来,并未增加到html文档中,要挪用appendChild或insertBefore等要领将其增加到HTML文档树中。

createTextNode

createTextNode用来建立一个文本节点,用法以下:

var textNode = document.createTextNode("一个TextNode");

createTextNode吸收一个参数,这个参数就是文本节点中的文本,和createElement一样,建立后的文本节点也只是自力的一个节点,一样需要appendChild将其增加到HTML文档树中。

cloneNode

cloneNode是用来返回挪用要领的节点的一个副本,它吸收一个bool参数,用来示意是不是复制子元素,运用以下:

var parent = document.getElementById("parentElement"); 
var parent2 = parent.cloneNode(true);// 传入true
parent2.id = "parent2";

这段代码经由历程cloneNode复制了一份parent元素,个中cloneNode的参数为true,示意parent的子节点也被复制,假如传入false,则示意只复制了parent节点。

我们看看这个例子:

<div id="parent">
    我是父元素的文本
    <br/>
    <span>
        我是子元素
    </span>
</div>
<button id="btnCopy">复制</button>

var parent = document.getElementById("parent");
document.getElementById("btnCopy").onclick = function(){
    var parent2 = parent.cloneNode(true);
    parent2.id = "parent2";
    document.body.appendChild(parent2);
}

这段代码很简朴,重如果绑定button事宜,事宜内容是复制了一个parent,修正其id,然后增加到文档中。
这里有几点要注重:

(1)和createElement一样,cloneNode建立的节点只是游离有html文档外的节点,要挪用appendChild要领才增加到文档树中
(2)假如复制的元素有id,则其副本一样会包含该id,由于id具有唯一性,所以在复制节点后必需要修正其id
(3)挪用吸收的bool参数最好传入,假如不传入该参数,差别浏览器对其默认值的处置惩罚能够差别

除此之外,我们另有一个需要注重的点:
假如被复制的节点绑定了事宜,则副本也会跟着绑定该事宜吗?这里要分状况议论:
(1)假如是经由历程addEventListener或许比方onclick举行绑定事宜,则副本节点不会绑定该事宜
(2)假如是内联体式格局绑定比方:

<div onclick="showParent()"></div>

如许的话,副本节点一样会触发事宜。

createDocumentFragment

createDocumentFragment要领用来建立一个DocumentFragment。在前面我们说到DocumentFragment示意一种轻量级的文档,它的作用重如果存储临时的节点用来预备增加到文档中。
createDocumentFragment要领重如果用于增加大批节点到文档中时会运用到。假定要轮回一组数据,然后建立多个节点增加到文档中,比方示例:

<ul id="list"></ul>
<input type="button" value="增加多项" id="btnAdd" />

document.getElementById("btnAdd").onclick = function(){
    var list = document.getElementById("list");
    for(var i = 0;i < 100; i++){
        var li = document.createElement("li");
        li.textContent = i;
        list.appendChild(li);
    }
}

这段代码将按钮绑定了一个事宜,这个事宜建立了100个li节点,然后顺次将其增加HTML文档中。如许做有一个瑕玷:每次一建立一个新的元素,然后增加到文档树中,这个历程会形成浏览器的回流。所谓回流简朴说就是指元素大小和位置会被从新盘算,假如增加的元素太多,会形成机能题目。这个时刻,就是运用createDocumentFragment了。
DocumentFragment不是文档树的一部分,它是保存在内存中的,所以不会形成回流题目。我们修正上面的代码以下:

document.getElementById("btnAdd").onclick = function(){
    var list = document.getElementById("list");    
    var fragment = document.createDocumentFragment();

    for(var i = 0;i < 100; i++){
      var li = document.createElement("li");
        li.textContent = i;
        fragment.appendChild(li);
    }

    list.appendChild(fragment);
}

优化后的代码重如果建立了一个fragment,每次天生的li节点先增加到fragment,末了一次性增加到list。

建立型API总结

建立型api重要包含createElement,createTextNode,cloneNode和createDocumentFragment四个要领,需要注重下面几点:
(1)它们建立的节点只是一个伶仃的节点,要经由历程appendChild增加到文档中
(2)cloneNode要注重假如被复制的节点是不是包含子节点以及事宜绑定等题目
(3)运用createDocumentFragment来处理增加大批节点时的机能题目

页面修正型API

前面我们提到建立型api,它们只是建立节点,并没有真正修正到页面内容,而是要挪用appendChild来将其增加到文档树中。我在这里将这类会修正到页面内容归为一类。
修正页面内容的api重要包含:appendChild,insertBefore,removeChild,replaceChild。

appendChild

appendChild我们在前面已用到屡次,就是将指定的节点增加到挪用该要领的节点的子元素的末端。挪用要领以下:

parent.appendChild(child);

child节点将会作为parent节点的末了一个子节点。
appendChild这个要领很简朴,然则另有有一点需要注重:假如被增加的节点是一个页面中存在的节点,则实行后这个节点将会增加到指定位置,其底本地点的位置将移除该节点,也就是说不会同时存在两个该节点在页面上,相当于把这个节点挪动到另一个处所。我们来看例子:

<div id="child">
    要被增加的节点
</div>
<br/>
<br/>
<br/>
<div id="parent">
    要挪动的位置
</div>        
<input id="btnMove" type="button" value="挪动节点" />

document.getElementById("btnMove").onclick = function(){
    var child = document.getElementById("child");
    document.getElementById("parent").appendChild(child);
}

这段代码重如果猎取页面上的child节点,然后增加到指定位置,能够看到底本的child节点被挪动到parent中了。
这里另有一个要注重的点:假如child绑定了事宜,被挪动时,它依旧绑定着该事宜。

insertBefore

insertBefore用来增加一个节点到一个参照节点之前,用法以下:

parentNode.insertBefore(newNode,refNode);

parentNode示意新节点被增加后的父节点
newNode示意要增加的节点
refNode示意参照节点,新节点会增加到这个节点之前
我们来看这个例子:

<div id="parent">
    父节点
    <div id="child">                
        子元素
    </div>
</div>
<input type="button" id="insertNode" value="插进去节点" />

var parent = document.getElementById("parent");
var child = document.getElementById("child");
document.getElementById("insertNode").onclick = function(){
    var newNode = document.createElement("div");
    newNode.textContent = "新节点"
    parent.insertBefore(newNode,child);
}

这段代码建立了一个新节点,然后增加到child节点之前。
和appendChild一样,假如插进去的节点是页面上的节点,则会挪动该节点到指定位置,而且保存其绑定的事宜。

关于第二个参数参照节点另有几个注重的处所:

(1)refNode是必传的,假如不传该参数会报错
(2)假如refNode是undefined或null,则insertBefore会将节点增加到子元素的末端

removeChild

removeChild望文生义,就是删除指定的子节点并返回,用法以下:

var deletedChild = parent.removeChild(node);

deletedChild指向被删除节点的援用,它即是node,被删除的节点依然存在于内存中,能够对其举行下一步操纵。
注重:假如被删除的节点不是其子节点,则递次将会报错。我们能够经由历程下面的体式格局来确保能够删除:

if(node.parentNode){
    node.parentNode.removeChild(node);
}

经由历程节点自身猎取节点的父节点,然后将自身删除。

replaceChild

replaceChild用于运用一个节点替代另一个节点,用法以下:

parent.replaceChild(newChild,oldChild);

newChild是替代的节点,能够是新的节点,也能够是页面上的节点,假如是页面上的节点,则其将被转移到新的位置
oldChild是被替代的节点

页面修正型API总结

页面修正型api重如果这四个接口,要注重几个特性:
(1)不管是新增照样替代节点,假如新增或替代的节点是底本存在页面上的,则其本来位置的节点将被移除,也就是说同一个节点不能存在于页面的多个位置
(2)节点自身绑定的事宜会不会消逝,会一向保存着。

节点查询型API

节点查询型API也是异常经常运用的api,下面我们离别申明一下每一个api的运用。

document.getElementById

这个接口很简朴,依据元素id返回元素,返回值是Element范例,假如不存在该元素,则返回null。
运用这个接口有几点要注重:
(1)元素的Id是大小写敏感的,肯定要写对元素的id
(2)HTML文档中能够存在多个id雷同的元素,则返回第一个元素
(3)只从文档中举行搜刮元素,假如建立了一个元素并指定id,但并没有增加到文档中,则这个元素是不会被查找到的

document.getElementsByTagName

这个接口依据元素标署名猎取元素,返回一个立即的HTMLCollection范例,什么是立即的HTMLCollection范例呢?我们来看看这个示例:

<div>div1</div>
<div>div2</div>
        
<input type="button" value="显现数目" id="btnShowCount"/>
<input type="button" value="新增div" id="btnAddDiv"/>    

var divList = document.getElementsByTagName("div");
document.getElementById("btnAddDiv").onclick = function(){
    var div = document.createElement("div");
    div.textContent ="div" + (divList.length+1);
    document.body.appendChild(div);
}
    
document.getElementById("btnShowCount").onclick = function(){
        alert(divList.length);
}

这段代码中有两个按钮,一个按钮是显现HTMLCollection元素的个数,另一个按钮能够新增一个div标签到文档中。前面提到HTMLCollcetion元素是立即的示意该鸠合是随时变化的,也就是是文档中有几个div,它会随时举行变化,当我们新增一个div后,再接见HTMLCollection时,就会包含这个新增的div。

运用document.getElementsByTagName这个要领有几点要注重:

(1)假如要对HTMLCollection鸠合举行轮回操纵,最好将其长度缓存起来,由于每次轮回都会去盘算长度,临时缓存起来能够进步效力
(2)假如没有存在指定的标签,该接口返回的不是null,而是一个空的HTMLCollection
(3)“*”示意一切标签

document.getElementsByName

getElementsByName重如果经由历程指定的name属性来猎取元素,它返回一个立即的NodeList对象。
运用这个接口重要要注重几点:

(1)返回对象是一个立即的NodeList,它是随时变化的
(2)在HTML元素中,并非一切元素都有name属性,比方div是没有name属性的,然则假如强迫设置div的name属性,它也是能够被查找到的
(3)在IE中,假如id设置成某个值,然后传入getElementsByName的参数值和id值一样,则这个元素是会被找到的,所以最好不好设置一样的值给id和name

document.getElementsByClassName

这个API是依据元素的class返回一个立即的HTMLCollection,用法以下:

var elements = document.getElementsByClassName(names);

这个接口有下面几点要注重:

(1)返回效果是一个立即的HTMLCollection,会随时依据文档构造变化
(2)IE9以下浏览器不支持
(3)假如要猎取2个以上classname,可传入多个classname,每一个用空格相隔,比方:

var elements = document.getElementsByClassName("test1 test2");

document.querySelector和document.querySelectorAll

这两个api很类似,经由历程css挑选器来查找元素,注重挑选器要相符CSS挑选器的划定规矩。
起首来引见一下document.querySelector。
document.querySelector返回第一个婚配的元素,假如没有婚配的元素,则返回null。
注重,由于返回的是第一个婚配的元素,这个api运用的深度优先搜刮来猎取元素。我们来看这个例子:

<div>
    <div>
        <span class="test">第三级的span</span>    
    </div>
</div>
<div class="test">            
    同级的第二个div
</div>
<input type="button" id="btnGet" value="猎取test元素" />

document.getElementById("btnGet").addEventListener("click",function(){
    var element = document.querySelector(".test");
    alert(element.textContent);
})

这个例子很简朴,就是两个class都包含“test”的元素,一个在文档树的前面,然则它在第三级,另一个在文档树的背面,但它在第一级,经由历程querySelector猎取元素时,它经由历程深度优先搜刮,拿到文档树前面的第三级的元素。

document.querySelectorAll的差别之处在于它返回的是一切婚配的元素,而且能够婚配多个挑选符,我们来看看下面这个例子:

<div class="test">
    class为test
</div>
<div id="test">
    id为test
</div>
<input id="btnShow" type="button" value="显现内容" />

document.getElementById("btnShow").addEventListener("click",function(){
    var elements = document.querySelectorAll("#test,.test");    
    for(var i = 0,length = elements.length;i<length;i++){
        alert(elements[i].textContent);
    }    
})

这段代码经由历程querySelectorAll,运用id挑选器和class挑选器挑选了两个元素,并顺次输出其内容。要注重两点:

(1)querySelectorAll也是经由历程深度优先搜刮,搜刮的元素递次和挑选器的递次无关
(2)返回的是一个非立即的NodeList,也就是说效果不会跟着文档树的变化而变化

兼容性题目:querySelector和querySelectorAll在ie8以下的浏览器不支持。

节点关联型api

在html文档中的每一个节点之间的关联都能够看成是家谱关联,包含父子关联,兄弟关联等等,下面我们顺次来看看每一种关联。

父关联型api

parentNode:每一个节点都有一个parentNode属性,它示意元素的父节点。Element的父节点多是Element,Document或DocumentFragment。

parentElement:返回元素的父元素节点,与parentNode的区分在于,其父节点必需是一个Element,假如不是,则返回null

兄弟关联型api

previousSibling:节点的前一个节点,假如该节点是第一个节点,则为null。注重有能够拿到的节点是文本节点或解释节点,与预期的不符,要举行处置惩罚一下。

previousElementSibling:返回前一个元素节点,前一个节点必需是Element,注重IE9以下浏览器不支持。

nextSibling:节点的后一个节点,假如该节点是末了一个节点,则为null。注重有能够拿到的节点是文本节点,与预期的不符,要举行处置惩罚一下。

nextElementSibling:返回后一个元素节点,后一个节点必需是Element,注重IE9以下浏览器不支持。

子关联型api

childNodes:返回一个立即的NodeList,示意元素的子节点列表,子节点能够会包含文本节点,解释节点等。
children:一个立即的HTMLCollection,子节点都是Element,IE9以下浏览器不支持。
firstChild:第一个子节点。
lastChild:末了一个子节点。
hasChildNodes要领:能够用来推断是不是包含子节点。

元素属性型api

setAttribute

setAttribute:依据称号和值修正元素的特性,用法以下:

element.setAttribute(name, value);

个中name是特性名,value是特性值。假如元素不包含该特性,则会建立该特性并赋值。
假如元素自身包含指定的特性名为属性,则能够天下接见属性举行赋值,比方下面两条代码是等价的:

element.setAttribute("id","test");

element.id = "test";

getAttribute

getAttribute返回指定的特性名响应的特性值,假如不存在,则返回null或空字符串。用法以下:

var value = element.getAttribute("id");

元素款式型api

直接修正元素的款式

elem.style.color = 'red';
elem.style.setProperty('font-size', '16px');
elem.style.removeProperty('color');

动态增加款式划定规矩

var style = document.createElement('style');
style.innerHTML = 'body{color:red} #top:hover{background-color: red;color: white;}';
document.head.appendChild(style);

window.getComputedStyle

经由历程element.sytle.xxx只能猎取到内联款式,借助window.getComputedStyle能够猎取应用到元素上的一切款式,IE8或更低版本不支持此要领。

var style = window.getComputedStyle(element[, pseudoElt]);

element是要猎取的元素,pseudoElt指定一个伪元素举行婚配。
返回的style是一个CSSStyleDeclaration对象。
经由历程style能够接见到元素盘算后的款式

getBoundingClientRect

getBoundingClientRect用来返回元素的大小以及相对于浏览器可视窗口的位置,兼容性异常好(IE6+),用法以下:

var clientRect = element.getBoundingClientRect();

clientRect是一个DOMRect对象,包含left,top,right,bottom,它是相对于可视窗口的间隔,转动位置发作转变时,它们的值是会发作变化的。除了IE9以下浏览器,还包含元素的height和width等数据,详细可检察链接

参考

转载地点:http://luopq.com/2015/11/30/j…
参考地点:http://blog.liuxianan.com/jav…

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