示例:获取 DOM 节点的 Demo
<div id="div1" class="container">
<p>一段文字</p>
<p>一段文字</p>
<p>一段文字</p>
</div>
<div id="div2" class="container">
<img src="./code.png">
</div>
const div1 = document.getElementById('div1')
console.log('div1', div1)
const divList = document.getElementsByTagName('div')
console.log('divList.length', divList.length)
console.log('divList[1]', divList[1])
const containerList = document.getElementsByClassName('container')
console.log('containerList.length', containerList.length)
console.log('containerList[1]', containerList[1])
const pList = document.querySelectorAll('p')
console.log('pList', pList)

示例 1:property 修改对象属性(推荐使用)
.container {
border: 1px solid #ccc;
}
.red {
color: red;
}
<div id="div1" class="container">
<p>一段文字1</p>
<p>一段文字2</p>
<p>一段文字3</p>
</div>
// property 形式
const pList = document.querySelectorAll('p')
const p1 = pList[0]
p1.style.width = '100px'
console.log(p1.style.width)
p1.className = 'red'
console.log(p1.className)
console.log(p1.nodeName)
console.log(p1.nodeType)

示例 2:attribute 修改 html 属性
.container {
border: 1px solid #ccc;
}
.red {
color: red;
}
<div id="div1" class="container">
<p>一段文字1</p>
<p>一段文字2</p>
<p>一段文字3</p>
</div>
// attribute
const pList = document.querySelectorAll('p')
const p1 = pList[0]
p1.setAttribute('data-name', 'imooc')
console.log(p1.getAttribute('data-name'))
p1.setAttribute('style', 'font-size: 30px;')
console.log(p1.getAttribute('style'))


示例:
<div id="div1" class="container">
<p id="p1">一段文字1</p>
<p>一段文字2</p>
<p>一段文字3</p>
</div>
<div id="div2" class="container"></div>
const div1 = document.getElementById('div1')
const div2 = document.getElementById('div2')
const newP = document.createElement('p')
// 新建节点
newP.innerHTML = '新增的一段文字'
// 插入节点
div1.appendChild(newP)
// 移动节点
const p1 = document.getElementById('p1')
div2.appendChild(p1)

示例 1:div1ChildNodes 不是数组,需要Array.from() 转为数组
<div id="div1" class="container">
<p id="p1">一段文字1</p>
<p>一段文字2</p>
<p>一段文字3</p>
</div>
const div1 = document.getElementById('div1')
// 获取父元素
console.log(p1.parentNode)
// 获取子元素列表
const div1ChildNodes = div1.childNodes
console.log(div1.childNodes)
const divChildNodesP = Array.from(div1ChildNodes).filter(child => {
if(child.nodeType === 1) {
return true
}
return false
})
console.log('divChildNodesP', divChildNodesP)

示例:在上文的基础上进行删除子元素
div1.removeChild(divChildNodesP[0])

示例 1:
// 不缓存 DOM 查询结果
for(let i = 0; i < document.getElementsByTagName('p').length; i++) {
// 每次循环,都会计算 length,频繁进行 DOM 查询
}
示例 2:
// 缓存 DOM 查询结果
const pList = document.getElementsByTagName('p')
const length = pList.length
for(let i = 0; i < length; i++) {
// 缓存 length,只进行一次 DOM 查询
}
示例 1:频繁的 DOM 操作
<ul id="list"></ul>
const list = document.getElementById('list')
for(let i = 0; i < 10; i++) {
const li = document.createElement('li')
li.innerHTML = `List item ${i}`
list.appendChild(li)
}
示例 2:创建文档片段
<ul id="list"></ul>
const list = document.getElementById('list')
// 创建一个文档片段,此时还没有插入到 DOM 树中
const frag = document.createDocumentFragment()
// 执行插入
for(let i = 0; i <= 10; i++) {
const li = document.createElement('li')
li.innerHTML = `List item ${i}`
// 先插入文档片段中
frag.appendChild(li)
}
// 都完成之后,再统一插入到 DOM 树中
list.appendChild(frag)



示例:通用事件绑定函数
<button id="btn1">一个按钮</button>
function bindEvent(elem, type, fn) {
elem.addEventListener(type, fn)
}
const btn1 = document.getElementById('btn1')
bindEvent(btn1, 'click', event => {
console.log(event.target) //
alert('clicked')
})

<div id="div1">
<p id="p1">激活</p>
<p id="p2">取消</p>
<p id="p3">取消</p>
<p id="p4">取消</p>
</div>
<div id="div2">
<p id="p5">取消</p>
<p id="p6">取消</p>
</div>
function bindEvent(elem, type, fn) {
elem.addEventListener(type, fn)
}
const p1 = document.getElementById('p1')
const body = document.body
bindEvent(p1, 'click', event => {
event.stopPropagation() // 阻止冒泡
console.log('激活')
})
bindEvent(body, 'click', event => {
console.log('取消')
})
不阻止冒泡,点击激活会冒泡到取消:

阻止冒泡,点击激活不会冒泡:

示例:元素 a 把事件处理委托给自己的父元素 div 去处理
<div id="div1">
<a href="#">a1</a>
<a href="#">a2</a>
<a href="#">a3</a>
<a href="#">a4</a>
<button>加载更多...</button>
</div>
function bindEvent(elem, type, fn) {
elem.addEventListener(type, fn)
}
const div1 = document.getElementById('div1')
bindEvent(div1, 'click', event => {
event.preventDefault() // 阻止页面跳转
const target = event.target
if(target.nodeName === 'A') {
alert(target.innerHTML)
}
})
点击 a1-4 会弹出对话框,点击按钮则不会:

<div id="div1">
<a href="#">a1</a>
<a href="#">a2</a>
<a href="#">a3</a>
<a href="#">a4</a>
<button>加载更多...</button>
</div>
<button id="btn1">点击</button>
// 通用事件绑定函数
function bindEvent(elem, type, selector, fn) {
// 如果传入三个参数,把 selector 赋值给 fn,selector 置空
if (fn == null) {
fn = selector
selector = null
}
elem.addEventListener(type, event => {
const target = event.target
if (selector) {
// 代理绑定
if (target.matches(selector)) {
fn.call(target, event)
}
} else {
// 普通绑定
fn.call(target, event)
}
})
}
// 普通绑定
const btn1 = document.getElementById('btn1')
bindEvent(btn1, 'click', function(event) {
event.preventDefault()
alert(this.innerHTML)
})
// 代理绑定
const div1 = document.getElementById('div1')
bindEvent(div1, 'click', 'a', function (event) {
event.preventDefault()
alert(this.innerHTML)
})
点击 a1-4 会弹出对话框,点击按钮则不会:

不积跬步无以至千里 不积小流无以成江海
点个关注不迷路,持续更新中…