DOM 操作是 JavaScript 中最令人兴奋的主题之一。这是因为 JavaScript 的主要用途之一是使网页具有交互性,而文档对象模型 (DOM) 在这方面发挥了重要作用。
DOM 是一个强大的工具,允许您与网页上的元素进行交互和操作。这本手册将帮助您理解并自信地使用它。
您将首先了解 DOM 是什么以及您可以用它做什么。然后,我们将深入探讨如何选择、修改和设置 DOM 元素的样式。您还将学习如何创建新元素并将它们添加到您的网页中。
DOM 是文档对象模型的缩写。它是一个 API,允许您以编程方式访问和操作 HTML 和 XML 文档的内容。
“文档”部分是指您在浏览器中看到的网页。具体来说,就是处理页面内容结构的 HTML 文档。这包括构成页面的文本、图像、链接和其他元素。
对象意味着图像、标题和段落等元素被视为对象。每个对象都有其属性(如 id、class、style)和方法。使用这些属性和方法,可以操作元素。
DOM 中的模型意味着它是 HTML 文档作为分层树的表示或副本。此树包含所有元素。它捕获了它们之间的父子关系。
DOM 始终与 HTML 文档相同。浏览器确保它们保持同步。因此,如果 HTML 中的某些内容发生了变化,DOM 也会发生变化,反之亦然。
层次结构的顶部是 Document 对象。它只有一个子元素—— html 元素。该 html 元素(也称为根元素)有两个子元素,即 head 和 body 元素。而且他们每个人都有自己的子元素。
元素之间的父子关系允许您遍历或移动并选择它们。稍后会详细介绍。
DOM 操作允许开发人员与网页的结构、样式和内容进行交互。以下是您可以使用 DOM 执行的一些操作:
要对 DOM 元素执行某些操作,首先必须选择或访问相关元素。在本节中,您将学习一些选择 DOM 元素的常用方法。
假如有如下 DOM 结构
<h1 id="page-title">Phonebook</h1>
<p class="family">Marie</p>
<p class="family">Jose</p>
<p class="work">Anne</p>
<p class="work">Joan</p>
获取 id 为 page-title 的元素
const pageTitle = document.getElementById('page-title')
console.log(pageTitle)
获取 class 为 family 的元素
const family = document.getElementsByClassName('family')
console.log(family)
console.log(family[0])
遍历元素
let famContactsArray = [...family]
famContactsArray.forEach((element) => console.log(element))
获取所有 p 元素
const paragraphs = document.getElementsByTagName('p')
let allContactsArray = [...paragraphs]
allContactsArray.map((element) => console.log(element))
获取第一个 class 为 work 的元素
const firstWorkContact = document.querySelector('.work')
console.log(firstWorkContact)
获取第 N 个元素
<div>
<button>First button</button>
<button>Second button</button>
<button>Third button</button>
<button>Fourth button</button>
</div>
const thirdButton = document.querySelector('div button:nth-child(3)')
console.log(thirdButton)
获取所有 button 元素
const allBtns = document.querySelectorAll('button')
console.log(allBtns)
遍历元素
allBtns.forEach((btn) => console.log(btn))
使用innerHTML
、textContent
、innerText
属性可以更改 DOM 元素的内容。
const pageTitle = document.getElementById('page-title')
pageTitle.innerHTML = 'Contacts'
使用innerHTML
会带来潜在的安全风险,比如可能会导致跨站脚本攻击(XSS)。因此,如果您不信任内容,最好不要使用innerHTML
。
务必在使用innerHTML
之前对内容进行严格的验证和过滤。比如使用DOMPurity
库。
如果使用纯文本,可以使用textContent
或innerText
。
const pageTitle = document.getElementById('page-title')
pageTitle.textContent = 'Contacts'
<img id="profile-pic" src="profile.jpg" alt="Profile picture" />
ImageElement.id的值是profile-pic
,ImageElement.src的值是profile.jpg
,ImageElement.alt的值是Profile picture
。
使用getAttribute
和setAttribute
方法可以获取和设置元素的属性。
获取 img 的 src 属性
const profilePic = document.getElementById('profile-pic')
console.log(profilePic.getAttribute('src'))
设置 img 的 src 属性
const profilePic = document.getElementById('profile-pic')
profilePic.setAttribute('src', 'new-profile.jpg')
移除 img 的 alt 属性
const profilePic = document.getElementById('profile-pic')
profilePic.removeAttribute('alt')
检查 img 是否有 alt 属性
const profilePic = document.getElementById('profile-pic')
console.log(profilePic.hasAttribute('alt'))
使用.style
属性或者classList
可以更改 DOM 元素的样式。
const pageTitle = document.getElementById('page-title')
pageTitle.style.color = 'red'
pageTitle.style.backgroundColor = 'yellow'
<p id="paragraph" class="family">Marie</p>
const paragraph = document.getElementById('paragraph')
paragraph.classList.add('friend')
paragraph.classList.remove('family')
判断元素是否有某个类
const paragraph = document.getElementById('paragraph')
console.log(paragraph.classList.contains('family'))
切换类
const paragraph = document.getElementById('paragraph')
paragraph.classList.toggle('family')
使用childNodes
、children
、firstChild
、lastChild
、nextSibling
、previousSibling
可以遍历 DOM 元素。
节点是 DOM 树中的所有对象的通用名称。元素是节点的一种类型。
<div>
<p>First paragraph</p>
<p>Second paragraph</p>
</div>
const firstParagraph = document.querySelector('p')
console.log(firstParagraph.parentNode)
console.log(firstParagraph.parentElement)
<div>
<p>First paragraph</p>
<p>Second paragraph</p>
</div>
const div = document.querySelector('div')
console.log(div.childNodes)
console.log(div.children)
<div>
<p>First paragraph</p>
<p>Second paragraph</p>
</div>
const div = document.querySelector('div')
console.log(div.firstChild)
console.log(div.lastChild)
<div>
<p>First paragraph</p>
<p>Second paragraph</p>
</div>
const firstParagraph = document.querySelector('p')
console.log(firstParagraph.nextSibling)
console.log(firstParagraph.previousSibling)
DOM 事件是在 HTML 文档中发生的事情。它可以是用户操作,也可以是浏览器操作。
事件监听是指在事件发生时执行的代码。事件监听器是一个函数,它会在事件发生时被调用。
事件监听是指在事件发生时执行的代码。事件处理程序是一个函数,它会在事件发生时被调用。
事件处理程序是事件监听器的一种。事件监听器是一个函数,它会在事件发生时被调用。
<button onclick="alert('Hello')">Click me</button>
<button id="btn">Click me</button>
const btn = document.getElementById('btn')
btn.onclick = function () {
alert('Hello')
}
<button id="btn">Click me</button>
const btn = document.getElementById('btn')
btn.addEventListener('click', function () {
alert('Hello')
})
事件对象是在事件发生时由浏览器创建的对象。它包含有关事件的信息,如事件类型、目标元素和鼠标位置。
<button id="btn">Click me</button>
const btn = document.getElementById('btn')
btn.addEventListener('click', function (event) {
console.log(event)
})
事件流描述了事件从页面中的元素传播到最外层元素的顺序。
事件冒泡是指事件从最内层元素向最外层元素传播的过程。
<div id="outer">
<div id="inner">Click me</div>
</div>
const inner = document.getElementById('inner')
const outer = document.getElementById('outer')
inner.addEventListener('click', function () {
console.log('Inner div clicked')
})
outer.addEventListener('click', function () {
console.log('Outer div clicked')
})
事件捕获是指事件从最外层元素向最内层元素传播的过程。
<div id="outer">
<div id="inner">Click me</div>
</div>
const inner = document.getElementById('inner')
const outer = document.getElementById('outer')
inner.addEventListener(
'click',
function () {
console.log('Inner div clicked')
},
true
)
outer.addEventListener(
'click',
function () {
console.log('Outer div clicked')
},
true
)
使用preventDefault
、stopPropagation
方法可以阻止事件的默认行为。
<a href="https://www.google.com" id="link">Google</a>
const link = document.getElementById('link')
link.addEventListener('click', function (event) {
event.preventDefault()
})
const btn = document.getElementById('btn')
btn.addEventListener('click', function (event) {
event.stopPropagation()
})