Dom总结
1.定义
文档对象模型 (DOM:Document Object Model) 是一个平台,一个中立于语言的应用程序编程接口 (API),允许程序访问并更改文档的内容、结构和样式
2.HTMLDOM
1)DOM 是将 HTML 文档表达为树结构, 定义了访问和操作 HTML 文档的标准方法;
2)DOM 树:节点(node)的层次。文档节点(document)、元素节点、属性节点、文本节点;
3)DOM 把一个文档表示为一棵家谱树(父,子,兄弟)。
注:属性节点,文本节点与元素节点是父子关系,但他俩不是兄弟节点。
2.2
节点的基本属性
一般来说节点至少拥有nodeType、nodeName和nodeValue这三个基本属性。节点类型不同,这三个属性的值也不相同。
基本属性的作用
nodeType
nodeType属性返回节点类型的常数值。不同的类型对应不同的常数值,12种类型分别对应1到12的常数值,比如文本节点类型为3
nodeName
nodeName属性返回节点的名称
nodeValue
nodeValue属性返回或设置当前节点的值,格式为字符串
3 元素获取的四种方法
getElementById,返回拥有指定 id 的第一个元素
getElementsByTagName(返回一个包括所有给定标签名称的元素集合),getElementsByClassName(返回一个包含所有指定class名称的元素集合),getElementsByName(返回一个包含所有指定 name 属性的元素集合)
4元素节点的属性操作
4.1获取属性节点
元素对象[“属性名”]
元素对象.属性名
元素对象.getAttribute(“属性名”);
4.2设置属性值
元素对象[”属性名”] = 值
元素对象.属性名 = 值
元素对象.setAttribute(“属性名”, 值)
// 获取、设置属性的值
// 1、通过 元素对象.属性名
console.log(divEle.id);
divEle.id = "div";
// 通过点的方式如果属性是class,需要使用 className 名字
console.log(divEle.className);
divEle.className = "熊大";
// 如果属性中有短杠的符号组合,在调用的时候需要去掉短杠,然后使用驼峰命名的方式
console.log(divEle.style.backgroundColor);
divEle.style.backgroundColor="green";
// 2、通过 元素对象[“属性名”]
console.log(divEle["id"]);
divEle["id"] = "div";
// 如果属性是class,需要使用 className 名字
console.log(divEle['className']);
divEle['className'] = "bbb"
// 如果属性中有短杠的符号组合,这2中方式都可以
console.log(divEle['style']["backgroundColor"]);
divEle['style']["backgroundColor"] = "red";
console.log(divEle['style']["background-color"]);
divEle['style']["background-color"] = "red";
// 3、元素对象.getAttribute("属性名")
var idValue = divEle.getAttribute("id");
console.log(idValue);
divEle.setAttribute("id", 10);
// 通过这种方式获取class属性,可以直接获取
var classNameValue = divEle.getAttribute("class");
console.log(classNameValue);
divEle.setAttribute("class", "c2");
// 标签中属性中的属性不能用 getAttribute 和 setAttribute
// 例如 style 中的 background-color 属性,下面这2种方式取到的值都为 null
var styleValue = divEle.getAttribute("backgroundColor");
var styleValue2 = divEle.getAttribute("background-color");
// 自定义属性
// 获取和设置自定义属性值只能通过 getAttribute() 和 setAttribute()
console.log(divEle.getAttribute("studentNo"));
divEle.setAttribute("studentNo", "250");
// 属性名和属性值相同的属性
//属性名和属性值相同的属性,此时使用JS获取到的属性值是 true/false
// checked="checked"
// selected="seleted"
// readonly="readonly"
var cb = document.getElementById("cb");
console.log(cb.checked);
4.3是否拥有属性
hasAttribute
4.4 dataset
获取html data-开头的属性,用法如下:
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>John Doe</div>
let el = document.querySelector('#user');
// el.id == 'user'
// el.dataset.id === '1234567890'
// el.dataset.user === 'johndoe'
// el.dataset.dateOfBirth === ''
el.dataset.dateOfBirth = '1960-10-03'; // set the DOB.
// 'someDataAttr' in el.dataset === false
el.dataset.someDataAttr = 'mydata';
// 'someDataAttr' in el.dataset === true
5.Node 节点
Node节点对象是元素节点对象、属性节点对象、文本节点对象和注释节点对象的父类,元素节点对象、属性节点对象、文本节点对象和注释节点对象都继承于Node节点对象。
属性如下:
6.常用的dom操作
6.1节点创建
6.1.1创建元素createElement
var elem = document.createElement("div");
elem.id = 'haorooms';
elem.style = 'color: red';
elem.innerHTML = '我是新创建的haorooms测试节点';
document.body.appendChild(elem);
6.1.2创建文本节点createTextNode
var node = document.createTextNode("我是文本节点");
document.body.appendChild(node);
6.1.3克隆一个节点cloneNode
node.cloneNode(true/false) ,它接收一个bool参数,用来表示是否复制子元素。
使用原生克隆方法之克隆属性和内联事件,对于通过事件监听器添加的事件并不会克隆,用 addEventListener 和 node.οnclick=xxx; 方式绑定的都不会复制。
var from = document.getElementById("test");
var clone = from.cloneNode(true);
clone.id = "test2";
document.body.appendChild(clone);
6.1.4 createDocumentFragment
本方法用来创建一个 DocumentFragment ,也就是文档碎片,它表示一种轻量级的文档,主要是用来存储临时节点,大量操作DOM时用它可以大大提升性能。
(如果使用appendChid方法将原DOM树中的节点添加到DocumentFragment中时,会删除原来的节点
DocumentFragment是DOM节点。它们不是主DOM树的一部分。通常的用例是创建文档片段,将元素附加到文档片段,然后将文档片段附加到DOM树。在DOM树中,文档片段被其所有的子元素所代替。因为文档片段存在于内存中,并不在DOM树中,所以将子元素插入到文档片段时不会引起页面回流(对元素位置和几何上的计算)。因此,使用文档片段通常会带来更好的性能。
6.2 节点修改
6.2.1 appendChild
6.2.2 insertBefore
node.insertBefore(newnode,existingnode)
在现有元素上插入一个元素
<html>
<body>
<ul id="myList"><li>Coffee</li><li>Tea</li></ul>
<p id="demo">请点击按钮向列表插入一个项目。</p>
<button onclick="myFunction()">试一下</button>
<script>
function myFunction()
{
var newItem=document.createElement("LI")
var textnode=document.createTextNode("Water")
newItem.appendChild(textnode)
var list=document.getElementById("myList")
list.insertBefore(newItem,list.childNodes[0]);
}
</script>
<p><b>注释:</b><br>首先请创建一个 LI 节点,<br>然后创建一个文本节点,<br>然后向这个 LI 节点追加文本节点。<br>最后在列表中的首个子节点之前插入此 LI 节点。</p>
</body>
</html>
6.2.3 removeChild
var deletedChild = parent.removeChild(node);
deletedChild指向被删除节点的引用,它仍然存在于内存中,可以对其进行下一步操作。另外,如果被删除的节点不是其子节点,则将会报错。一般删除节点都是这么删的:
function removeNode(node)
{
if(!node) return;
if(node.parentNode) node.parentNode.removeChild(node);
}
6.2.4 replaceChild
node.replaceChild(newnode,oldnode)
<!DOCTYPE html>
<html>
<body>
<ul id="myList"><li>Coffee</li><li>Tea</li><li>Milk</li></ul>
<p id="demo">点击按钮来替换列表中的首个项目。</p>
<button onclick="myFunction()">试一下</button>
<script>
function myFunction()
{
var textnode=document.createTextNode("Water");
var item=document.getElementById("myList").childNodes[0];
item.replaceChild(textnode,item.childNodes[0]);
}
</script>
<p>首先创建一个新的文本节点。<br>然后替换首个列表项中的首个子节点。</p>
<p><b>注释:</b>本例用文本节点 "Water" 替换文本节点 "Coffee",而不是整个 LI 元素,这是替换节点的另一种方法。</p>
</body>
</html>
6.2.3 contains
Node.contains()返回的是一个布尔值,来表示传入的节点是否为该节点的后代节点
node.contains( otherNode )
node 是否包含otherNode节点.
otherNode 是否是node的后代节点.
如果 otherNode 是 node 的后代节点或是 node 节点本身.则返回true , 否则返回 false.
例题:描述:查找两个节点的最近的一个共同父节点,可以包括节点自身
输入描述:oNode1 和 oNode2 在同一文档中,且不会为相同的节点
function commonParentNode(oNode1, oNode2) {
while(true){
if(oNode1.contains(oNode2)){
return oNode1
}
oNode1 = oNode1.parentNode;
}
}
3.节点关系
6.3.1父关系
parentNode,parentElement
唯一区别:
在获取根部document节点是,parentElement找的是元素,因此报错null,而parentNode获取的是节点,返回的是#document
6.3.2子关系
children :返回一个实时的 HTMLCollection ,子节点都是Element,IE9以下浏览器不支持;
childNodes :返回一个实时的 NodeList ,表示元素的子节点列表,注意子节点可能包含文本节点、注释节点等;
firstChild :返回第一个子节点,不存在返回null,与之相对应的还有一个 firstElementChild
lastChild :返回最后一个子节点,不存在返回null,与之相对应的还有一个 lastElementChild
6.3.3 兄弟关系
previousSibling :节点的前一个节点,如果不存在则返回null。注意有可能拿到的节点是文本节点或注释节点,与预期的不符,要进行处理一下。
nextSibling :节点的后一个节点,如果不存在则返回null。注意有可能拿到的节点是文本节点,与预期的不符,要进行处理一下。
previousElementSibling :返回前一个元素节点,前一个节点必须是Element,注意IE9以下浏览器不支持。
nextElementSibling :返回后一个元素节点,后一个节点必须是Element,注意IE9以下浏览器不支持。
7.事件驱动
所谓事件驱动,简单地说就是你怎么触碰按钮(即产生什么事件),电脑执行什么操作(即调用什么函数)
核心对象包括4个点
事件源(谁发出事件通知,发出消息;也就是事件主体(通常指元素和标签)
事件对象(事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象event,它有很多属性和方法:
事件名称(发出什么样的通知的名称,比如鼠标到我头上了,我被别人点了一下
事件响应函数
<!--p元素是事件源 click是事件名称 -->
<p style="color: red" id="p1" onclick="shout(event);">Hello world!</p>
<script> //响应函数
function shout(e){ //响应函数,监听函数
alert(e.clientX); //e事件对象
}
</script>
7.1事件对象
事件处理函数提供一个形式参数,它是一个对象,封装了本次事件的细节。这个参数通常用 event 或者 e 表示。
7.1.1获取鼠标位置
a.pageX/pageY:获取鼠标相对于整张网页上面的水平/垂直坐标。
b.clientX/clientY:获取鼠标相对于浏览器窗口的水平/垂直坐标。
c.offestX/offestY:获取鼠标相对于事件源元素的水平/垂直坐标。
7.1.2 e.preventDefault():阻止默认事件
7.1.3 e.stopPropagation():阻止事件传播
终止事件在传播过程的捕获、目标处理或起泡阶段进一步传播。调用该方法后,该节点上处理该事件的处理程序将被调用,事件不再被分派到其他节点。
7.1.4 事件委托
e.target : 触发事件的元素,即 ” 事件源元素 “ 。是盒子里面最内元素。
e.currentTarget:事件处理程序附加到的元素,即添加事件的元素。