DOM Document Object Model文档对象模型
DOM本质:js对象
dom树是由各种各样的节点构成,获取的元素其实是DOM树中一个元素节点。
在 HTML DOM (Document Object Model) 中,
每一个元素都是 节点对象(Node object)。所有html标签元素称为元素节点对象(简称元素节点);所有html标签上的属性成为属性节点对象。
JavaScript中的所有节点都继承JS内部实现的Node基类。
DOM常见操作
获取元素节点
document.getElementById;element.getElementByTagName();element.getElementByClassName();element.querySeletor(selector);element.querySeletorAll(selector)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
DOM查找元素:getElementById getElementsByTagName getElementsByClassName
getElementById
根据id找元素,如果有多个相同id,只会找到第一个。如果找不大id,返回null
getElementById是document才可以调用的方法。
getElementsByTagName getElementsByClassName 根据html标签名或者类名查找元素
返回是HTMLCollection类数组对象,可以通过下标索引取值
HTML DOM 中的 HTMLCollection 是即时更新的(live);当其所包含的文档结构发生改变时,它会自动更新。
element.querySelector(selectors) element.querySelectorAll(selectors)
querySelector返回css选择器(html标签,class id都可以)第一个元素。找不到返回null
querySelectorAll 返回NodeList类数组对象集合,找不到返回NodeList []
在其他情况下,NodeList 是一个静态元素集合,也就意味着随后对文档对象模型的任何改动都不会影响集合的内容
设置和读取元素节点属性
innerHTML innerText outerHTML className style
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const fa = document.querySelector('.fa') const son = document.querySelector('.son') const a = document.querySelector('a') son.addEventListener('click', clickSon, false) fa.addEventListener('click', clickFa, false) function clickSon(event) { event = event || window.event event.stoppropagation ? event.stoppropagation() : event.cancelBubble = true console.log('son'); } function clickFa(event) { event = event || window.event console.log('fa'); }
attributes property
节点操作(增删改查)
增加节点并添加DOM中
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const wrapper = document.querySelector("#wrapper"); const newDiv = document.createElement("div"); //createElement是document特有方法 产生一个Node js对象 newDiv.innerHTML = "我是新加的元素"; const divStr = "<div>append</div>"; wrapper.appendChild(newDiv);
插入parentElement.insertBefore(newElement,oldElement)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const wrapper = document.querySelector("#wrapper"); //父节点 const demo = document.getElementById("demo"); //已经存在的子节点 const newDiv = document.createElement("div"); newDiv.innerHTML = "i am new"; wrapper.insertBefore(newDiv, demo); //parentElement.insertBefore(newElement,oldElement)
注意没有insertAfter方法。如果要需要自己实现
用新节点替换已有节点replaceChild
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const wrapper = document.querySelector("#wrapper"); //父节点 const demo = document.getElementById("demo"); //已经存在的子节点 const newDiv = document.createElement("div"); newDiv.innerHTML = `<p>i am new</p>`; wrapper.replaceChild(newDiv, demo);
cloneNode(fasle|true) 克隆节点 默认是false.表示不克隆子节点
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const wrapper = document.querySelector("#wrapper"); //父节点 const cloneWrapper = wrapper.cloneNode(true); document.body.appendChild(cloneWrapper);
删除节点
remove removeChild
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const wrapper = document.querySelector("#wrapper"); //父节点 const demo = document.querySelector("#demo"); wrapper.removeChild(demo); //父亲来杀 demo.remove(); //自杀
文档碎片document.createDocumentFragment()
提升DOM操作性能。只需要插入文档对象一次。并且文档对象是dom js元素存在内存中。追加到页面中,文档碎片被其所有的子元素代替。也就是文档碎片不会出现在DOM中
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const arr = [100, 200, 300]; const wrapper = document.getElementById("wrapper"); const frag = document.createDocumentFragment(); arr.forEach((item) => { const newP = document.createElement("p"); newP.innerHTML = item; frag.appendChild(newP); }); wrapper.appendChild(frag);
事件
事件是DOM元素天生自带的行为属性,我们操作元素就会触发对应事件行为。那为什么不触发效果?是因为没有给事件绑定方法
事件绑定:给dom元素天生自带的事件行为绑定方法。当事件触发就把绑定的方法执行。
常见元素天生自带的事件(名):鼠标事件 键盘事件 焦点事件
鼠标事件:click mousedown
键盘事件:keydown keypress keyup
焦点事件:blur focus(获取焦点)
事件绑定
DOM0级事件绑定:
element.onxxx=function(e){}
element.onxxx=null (解绑)
DOM2级事件绑定:
element.addEventListener(事件名,函数,boolean) boolean默认是false 表示在冒泡阶段执行函数
element.removeEventListener(事件名,函数,boolean) 解绑事件
DOM2和DOM0区别
DOM2可以绑定多个事件(事件名可以相同或者不同),依次执行,不会覆盖
通用型事件绑定和解绑(考虑兼容)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function bind(element, type, fn) { // DOM2级别事件绑定 if (element.addEventListener) { return element.addEventListener(type, fn, false) } // IEDOM2级别事件绑定 if (element.attachEvent) { return element.attachEvent('on' + type, fn) } // DOM0事件绑定 element['on' + type] = fn } function unbind(element, type, fn) { if (element.removeEventListener) return element.removeEventListener(type, fn, false) if (element.detachEvent) return element.detachEvent('on' + type, fn) //DOM2级别IE解绑 element['on' + type] = null // DOM0事件解绑 }
事件默认行为preventDefault
事件是元素天生自带的行为,有些事件触发了即使没有绑定方法,也会默认触发一些效果行为,这个就是默认行为
比如点击超链接会跳转
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
function handleClick(e) { e = e || window.event; e.preventDefault ? e.preventDefault() : e.returnValue = false e.preventDefault() } a.addEventListener('click', handleClick, false)
事件传播
阻止事件冒泡stoppropagation
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const fa = document.querySelector('.fa') const son = document.querySelector('.son') const a = document.querySelector('a') son.addEventListener('click', clickSon, false) fa.addEventListener('click', clickFa, false) function clickSon(event) { event = event || window.event event.stoppropagation ? event.stoppropagation() : event.cancelBubble = true console.log('son'); } function clickFa(event) { event = event || window.event console.log('fa'); }
事件委托
利用事件冒泡的机制,把事件绑定到父节点元素身上,从而管理子节点元素某一类事件
好处:1只需要给父节点元素绑定一个函数,就可以管理子元素节点某一类事件。显著减少内存消耗,提升性能。2动态增加的子元素节点自动注册事件
e.currentTarget: 当前正在处理事件的那个元素。同this指定的元素对象
e.target :事件源(也就是目标阶段的元素)
例子
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 点击任意的一个li 变红色 const ul = document.querySelector('ul') ul.addEventListener('click', changeSonColor, false); function changeSonColor(e) { e = e || window.event const li = e.target li.style.color = 'red' }
无线下拉的图片列表,如何监听每隔图片的点击? 还是事件代理。e.target e.nodeName="img"