小哆啦在面试的时候有一次被问到
DOM
由于经常使用框架开发,导致DOM
有点遗忘,然后呢就总结一下常用的DOMAPI
参考资料:
DOM 概述 - Web API 接口参考 | MDN (mozilla.org)
DOM对象内,有数百个属性和方法。DOM对象处理的核心,就是对DOM中的元素节点(即标签)
进行一些增、删、改、查、事件操作、属性操作等一系列操作。
DOM核心操作思维导图
DOM
核心api
——创建document.write()
document.write
是 JavaScript 中的一种方法,用于将文本或 HTML 写入到 HTML 文档中。这个方法通常用于在文档加载过程中动态生成内容。
用法
document.write(content);
content: 要写入到文档的文本或 HTML 内容。
注意事项
document.write
会在文档中直接插入内容,如果在文档加载后使用,它将覆盖整个文档。innerHTML
、createElement
等,以提高性能和代码可维护性。示例
document.write("Hello, World!");
- 写入文本内容
document.write("This is a heading
");
- 写入包含 HTML 标签的内容
var name = "John";
document.write("Hello, "
+ name + "!");
使用 document.write
时需要小心,尤其是在文档加载后。推荐使用更现代的 DOM 操作方法,以确保更好的性能和可维护性。
document.write
有一些性能问题,特别是在文档加载后使用时,可能会导致页面重绘和性能下降。现代的 DOM 操作方法通常更有效,因为它们可以更精确地控制何时进行 DOM 更新,以及如何进行更新。document.write
在大型项目中可能导致代码难以维护。现代的 DOM 操作方法提供了更清晰、模块化的代码结构,使代码更易于理解和维护。document.createElement
是 DOM 中的方法,用于创建新的 HTML 元素。这个方法接受一个参数,表示要创建的元素的标签名称,然后返回一个新创建的元素节点。
document.createElement()
用法
var newElement = document.createElement(tagName);
tagName
: 要创建的 HTML 元素的标签名称,例如 “div”、“p”、“span” 等。返回值
返回新创建的元素节点。
示例
// 创建一个新的 元素
var newDiv = document.createElement('div');
// 创建一个新的 元素
var newParagraph = document.createElement('p');
用途
-
动态生成元素: document.createElement
主要用于在 JavaScript 中动态生成 HTML 元素。这对于根据特定条件或用户交互生成新的页面内容非常有用。
// 创建一个新的
var newButton = document.createElement('button');
-
结合其他 DOM 操作: 结合其他 DOM 操作方法,如 appendChild
、setAttribute
,可以实现更复杂的元素创建和操作。
// 创建一个新的 元素,并设置属性和内容
var newLink = document.createElement('a');
newLink.href = 'https://www.example.com';
newLink.textContent = 'Visit Example';
// 将新的 元素添加到文档的 元素中
document.body.appendChild(newLink);
-
模板引擎和动态页面生成: 在使用 JavaScript 模板引擎或构建动态页面时,document.createElement
可以帮助动态创建页面元素。
// 使用模板引擎或其他数据源获取数据
var data = getDataFromTemplateEngine();
// 根据数据动态创建页面元素
var newElement = document.createElement('div');
newElement.textContent = data.value;
// 将新元素添加到文档中
document.body.appendChild(newElement);
注意事项
-
性能考虑: 尽管 document.createElement
是一个非常有用的方法,但在某些情况下可能涉及性能问题,特别是在循环中频繁使用。在这种情况下,最好考虑使用 document.createDocumentFragment
或其他优化方法。
-
属性和内容设置: 创建的元素默认是空的,需要使用其他 DOM 操作方法设置元素的属性和内容,例如 setAttribute
、textContent
。
var newDiv = document.createElement('div');
newDiv.setAttribute('class', 'new-div');
newDiv.textContent = 'This is a new div';
-
适度使用: 尽管动态生成元素对于某些场景很有用,但在可能的情况下,尽量减少对 DOM 的频繁操作,以提高性能。
-
就是单纯的新增一个元素,不会影响原来的内容,最好用
1.3 innerHTML
属性
用法
-
获取元素的 HTML 内容:
var elementContent = element.innerHTML;
-
设置元素的 HTML 内容:
element.innerHTML = newHTMLContent;
示例
// 获取元素的 HTML 内容
var currentHTML = document.getElementById('myElement').innerHTML;
// 设置元素的 HTML 内容
document.getElementById('myElement').innerHTML = 'New content
';
用途
-
获取和修改元素的 HTML 内容: 通过 innerHTML
,可以方便地获取元素当前的 HTML 内容,并在需要时修改它。
// 获取段落元素的 HTML 内容
var paragraphContent = document.getElementById('myParagraph').innerHTML;
// 修改段落元素的 HTML 内容
document.getElementById('myParagraph').innerHTML = 'New content';
-
动态生成和更新页面内容: innerHTML
可以在 JavaScript 中动态生成或更新页面内容,特别适用于将 HTML 字符串插入到元素中。
// 创建一个新的 div 元素并设置其 HTML 内容
var newDiv = document.createElement('div');
newDiv.innerHTML = 'This is a new div
';
// 将新元素添加到文档中
document.body.appendChild(newDiv);
注意事项
-
安全性: 直接使用 innerHTML
可能导致安全风险,因为它允许插入任意 HTML 代码。如果 HTML 内容来自不受信任的来源,必须谨慎使用以防止跨站脚本攻击(XSS)。
// 不安全的用法,潜在的 XSS 风险
var userInput = '';
document.getElementById('myElement').innerHTML = userInput;
-
性能考虑: 在频繁更新大量 HTML 内容时,innerHTML
可能不是最高效的选择,因为它会导致整个元素的重新解析和渲染。在这种情况下,考虑使用更高效的 DOM 操作方法,例如 document.createElement
和 appendChild
。
// 更高效的用法,使用 createElement 和 appendChild
var newDiv = document.createElement('div');
newDiv.innerHTML = 'This is a new div
';
document.body.appendChild(newDiv);
原理
-
如果直接用等号(=),也会覆盖原来的值
-
如果用加等(+=),从视觉角度没有覆盖,就是增加新元素
-
但是从原理角度:本质上是把原来的元素取出来,再和新的元素一起添加进去,其实也是覆盖了原来的内容,它会让原来的元素事件失效
就像正品和高仿,就算再像,也不 是同一个
2、DOM
核心api
——新增
2.1 appendChild()
appendChild
是 DOM 中的方法,用于将一个新的子节点添加到指定父节点的末尾。这个方法允许你将一个已经存在的节点或通过 document.createElement
创建的新节点添加到文档中的特定位置。
用法
parentNode.appendChild(childNode);
parentNode
: 要添加子节点的父节点。
childNode
: 要添加的子节点。
示例
// 创建一个新的 元素
var newParagraph = document.createElement('p');
newParagraph.textContent = 'This is a new paragraph';
// 将新的 元素添加到文档的
元素中
document.body.appendChild(newParagraph);
用途
-
动态生成和添加节点: appendChild
主要用于在 JavaScript 中动态生成节点,并将这些节点添加到文档中。这对于根据用户交互或其他条件生成新的页面内容非常有用。
// 创建一个新的 元素
var newDiv = document.createElement('div');
newDiv.textContent = 'This is a new div';
// 将新的 元素添加到文档的 元素中
document.body.appendChild(newDiv);
-
移动和重新排序节点: 除了添加新节点,appendChild
也可以用于将已经存在的节点从一个位置移动到另一个位置,以实现节点的重新排序。
// 获取已经存在的元素
var existingElement = document.getElementById('existingElement');
// 将现有元素移动到新的父元素中
newParentNode.appendChild(existingElement);
原理
-
创建新节点: 当通过 document.createElement
创建一个新节点时,该节点会在内存中被创建,但尚未连接到文档结构中。
-
调用 appendChild
: 当调用 appendChild
方法时,它会将指定的子节点添加到父节点的子节点列表的末尾。
-
更新文档结构: 添加节点后,文档结构会得到更新,新的节点成为了父节点的最后一个子节点。如果这个父节点在文档中有对应的元素,浏览器会渲染出相应的变化。
// 创建一个新的 元素
var newParagraph = document.createElement('p');
newParagraph.textContent = 'This is a new paragraph';
// 将新的 元素添加到文档的
元素中
document.body.appendChild(newParagraph);
在这个例子中,appendChild
将新创建的
元素添加到文档的
元素的末尾。
注意事项
-
重复添加: 如果已存在的节点被使用 appendChild
添加到另一个位置,它将从原来的位置移除,并在新的位置出现。如果尝试再次添加已存在的节点,它会从原来的位置移除,然后再次出现在新的位置。
// 获取已存在的元素
var existingElement = document.getElementById('existingElement');
// 第一次添加到新的父元素
newParentNode.appendChild(existingElement);
// 第二次添加到另一个新的父元素
anotherParentNode.appendChild(existingElement);
-
性能考虑: 在大量节点操作的情况下,频繁使用 appendChild
可能影响性能。考虑使用文档片段(DocumentFragment
)进行离线操作,最后再将整个片段一次性添加到文档中,以提高性能。
2.2 insertBefore()
insertBefore
是 DOM 中的方法,用于将一个新的子节点插入到指定父节点的子节点列表中的指定位置。这个方法允许你在指定参考节点之前插入一个新的子节点。
用法
parentNode.insertBefore(newNode, referenceNode);
parentNode
: 要插入子节点的父节点。
newNode
: 要插入的新节点。
referenceNode
: 插入位置的参考节点,新节点将插入到它的前面。
示例
// 创建一个新的 元素
var newParagraph = document.createElement('p');
newParagraph.textContent = 'This is a new paragraph';
// 获取参考节点,例如已存在的元素
var referenceElement = document.getElementById('referenceElement');
// 将新的 元素插入到参考节点之前
document.body.insertBefore(newParagraph, referenceElement);
用途
-
动态生成和插入节点: insertBefore
主要用于在 JavaScript 中动态生成节点,并将这些节点插入到文档中的指定位置。这对于根据用户交互或其他条件生成新的页面内容非常有用。
// 创建一个新的 元素
var newDiv = document.createElement('div');
newDiv.textContent = 'This is a new div';
// 获取参考节点
var referenceElement = document.getElementById('referenceElement');
// 将新的 元素插入到参考节点之前
document.body.insertBefore(newDiv, referenceElement);
-
节点的重新排序: 除了添加新节点,insertBefore
也可以用于将已经存在的节点从一个位置移动到另一个位置,以实现节点的重新排序。
// 获取已经存在的元素
var existingElement = document.getElementById('existingElement');
// 获取参考节点
var referenceElement = document.getElementById('referenceElement');
// 将现有元素移动到参考节点之前
document.body.insertBefore(existingElement, referenceElement);
原理
-
确定插入位置: insertBefore
方法首先确定新节点要插入的位置,即参考节点之前。
-
更新父节点的子节点列表: 一旦确定插入位置,insertBefore
会将新节点插入到父节点的子节点列表中的指定位置。新节点将成为指定参考节点的前一个兄弟节点。
-
更新文档结构: 添加节点后,文档结构会得到更新,新的节点成为了指定参考节点的前一个兄弟节点。如果这个父节点在文档中有对应的元素,浏览器会渲染出相应的变化。
-
原来的位置移除,然后重新插入到新的位置。
// 创建一个新的 元素
var newParagraph = document.createElement('p');
newParagraph.textContent = 'This is a new paragraph';
// 获取参考节点
var referenceElement = document.getElementById('referenceElement');
// 将新的 元素插入到参考节点之前
document.body.insertBefore(newParagraph, referenceElement);
在这个例子中,insertBefore
将新创建的
元素插入到参考节点之前。
注意事项
-
参考节点不能为空: referenceNode
参数不能为 null
,否则会抛出错误。确保有一个有效的参考节点。
-
克隆节点: 如果要在多个位置插入同一个节点,需要先使用 cloneNode
方法克隆一份节点,以避免同一个节点在 DOM 结构中的多个位置引用的问题。
// 创建一个新的 元素
var newDiv = document.createElement('div');
newDiv.textContent = 'This is a new div';
// 获取参考节点
var referenceElement = document.getElementById('referenceElement');
// 克隆节点并插入到参考节点之前
document.body.insertBefore(newDiv.cloneNode(true), referenceElement);
-
性能考虑: 在大量节点操作的情况下,频繁使用 insertBefore
可能影响性能。考虑使用文档片段(DocumentFragment
)进行离线操作,最后再将整个片段一次性添加到文档中,以提高性能。
2.3 cloneNode()
cloneNode
是 DOM 中的方法,用于创建调用该方法的节点的一个克隆。通过 cloneNode
方法,你可以生成一个节点的副本,可以选择是否深度克隆子节点,也可以选择克隆节点时是否保留所有属性。两种方式的克隆,都不包含事件
用法
var clonedNode = node.cloneNode(deep);
node
: 要克隆的节点。
deep
(可选): 一个布尔值,指定是否深度克隆节点的子节点。默认为 false
,即只克隆节点本身而不包括子节点。
示例
// 获取一个已存在的元素
var originalElement = document.getElementById('originalElement');
// 浅克隆,只克隆元素本身
var shallowClone = originalElement.cloneNode();
// 深克隆,克隆元素及其所有子节点
var deepClone = originalElement.cloneNode(true);
用途
-
创建节点副本: cloneNode
主要用于创建节点的副本,可以选择是否包括节点的子节点。
// 获取一个已存在的元素
var originalElement = document.getElementById('originalElement');
// 克隆元素及其所有子节点
var deepClone = originalElement.cloneNode(true);
-
避免节点引用问题: 在 DOM 操作中,有时需要在不影响原始节点的情况下使用节点的副本。这可以避免引用相同节点导致的问题。
// 获取一个已存在的元素
var originalElement = document.getElementById('originalElement');
// 克隆元素,以避免引用相同节点
var clonedElement = originalElement.cloneNode(true);
// 将克隆节点添加到文档中
document.body.appendChild(clonedElement);
注意事项
-
深度克隆和浅克隆: 在使用 cloneNode
时,可以选择是否深度克隆节点的子节点。如果 deep
参数为 true
,则会深度克隆,包括子节点;如果为 false
,则只克隆节点本身而不包括子节点。默认为浅克隆。
// 浅克隆,只克隆元素本身
var shallowClone = originalElement.cloneNode();
// 深克隆,克隆元素及其所有子节点
var deepClone = originalElement.cloneNode(true);
-
事件处理程序: cloneNode
默认不会克隆节点的事件处理程序。如果需要复制事件处理程序,需要在克隆节点后手动重新绑定事件。
// 获取一个带有点击事件的元素
var originalElement = document.getElementById('originalElement');
originalElement.addEventListener('click', function() {
alert('Original element clicked');
});
// 克隆节点,默认不复制事件处理程序
var clonedElement = originalElement.cloneNode();
// 重新绑定点击事件到克隆节点
clonedElement.addEventListener('click', function() {
alert('Cloned element clicked');
});
总体而言,cloneNode
是一个在 DOM 操作中非常有用的方法,允许你创建节点的独立副本,以满足不同的需求。
3、DOM
核心api
——删除
3.1 removeChild()
removeChild
是 DOM 中的方法,用于从父节点中移除指定的子节点。通过 removeChild
方法,你可以动态地从文档中移除一个节点,这也会触发相应的 DOM 结构的更新。
用法
var removedNode = parentNode.removeChild(childNode);
parentNode
: 要移除子节点的父节点。
childNode
: 要移除的子节点。
示例
// 获取父节点
var parentElement = document.getElementById('parentElement');
// 获取要移除的子节点
var childElement = document.getElementById('childElement');
// 从父节点中移除子节点
var removedNode = parentElement.removeChild(childElement);
用途
-
动态移除节点: removeChild
主要用于从文档中动态移除节点。这对于根据用户交互或其他条件删除页面内容非常有用。
// 获取父节点
var parentElement = document.getElementById('parentElement');
// 获取要移除的子节点
var childElement = document.getElementById('childElement');
// 从父节点中移除子节点
parentElement.removeChild(childElement);
-
节点的重新排序: 除了删除节点,removeChild
也可以用于将已经存在的节点从一个位置移动到另一个位置,以实现节点的重新排序。
// 获取父节点
var parentElement = document.getElementById('parentElement');
// 获取已经存在的元素
var existingElement = document.getElementById('existingElement');
// 从父节点中移除现有元素
parentElement.removeChild(existingElement);
注意事项
-
返回值: removeChild
方法返回被移除的节点的引用。这可以用于在移除节点后进行进一步的操作或在其他地方重新插入节点。
// 获取父节点
var parentElement = document.getElementById('parentElement');
// 获取要移除的子节点
var childElement = document.getElementById('childElement');
// 从父节点中移除子节点,并保存被移除的节点的引用
var removedNode = parentElement.removeChild(childElement);
// 在其他地方重新插入被移除的节点
document.body.appendChild(removedNode);
-
不存在的子节点: 如果尝试移除不存在的子节点,removeChild
方法将抛出一个错误。因此,在使用 removeChild
之前,最好检查一下要移除的节点是否存在。
// 获取父节点
var parentElement = document.getElementById('parentElement');
// 获取要移除的子节点
var childElement = document.getElementById('nonexistentElement');
// 在移除之前检查节点是否存在
if (childElement) {
parentElement.removeChild(childElement);
}
总体而言,removeChild
提供了一种方便的方式来在 DOM 中动态移除节点,以满足页面交互和动态内容更新的需求。
4、DOM
核心api
——替换
4.1 replaceChild()
replaceChild
是 DOM 中的方法,用于将一个子节点替换为另一个节点。通过 replaceChild
方法,你可以动态地更改文档结构,用新的节点替换现有的子节点。
用法
var replacedNode = parentNode.replaceChild(newNode, oldNode);
parentNode
: 要替换子节点的父节点。
newNode
: 要插入的新节点。
oldNode
: 要替换的现有子节点。
示例
// 获取父节点
var parentElement = document.getElementById('parentElement');
// 创建新节点
var newNode = document.createElement('div');
newNode.textContent = 'This is the new content';
// 获取要替换的现有节点
var oldNode = document.getElementById('oldNode');
// 替换现有节点为新节点
var replacedNode = parentElement.replaceChild(newNode, oldNode);
在上述示例中,replaceChild
方法用新创建的 div
节点替换了现有的 oldNode
节点。
用途
-
动态更新内容: replaceChild
方法允许你在不重新加载整个页面的情况下动态更新页面内容。这对于响应用户交互或其他事件时非常有用。
// 获取父节点
var parentElement = document.getElementById('parentElement');
// 创建新节点
var newNode = document.createElement('div');
newNode.textContent = 'Updated content';
// 获取要替换的现有节点
var oldNode = document.getElementById('oldNode');
// 替换现有节点为新节点
var replacedNode = parentElement.replaceChild(newNode, oldNode);
-
动态切换元素: 你可以使用 replaceChild
方法在同一位置动态切换不同的元素,以根据应用程序状态更改页面的外观和行为。
// 获取父节点
var parentElement = document.getElementById('parentElement');
// 创建两个不同的节点
var node1 = document.createElement('div');
node1.textContent = 'Content 1';
var node2 = document.createElement('div');
node2.textContent = 'Content 2';
// 初始时使用第一个节点
var currentChild = parentElement.replaceChild(node1, oldNode);
// 在某个事件触发时切换到第二个节点
setTimeout(function() {
parentElement.replaceChild(node2, currentChild);
}, 2000);
注意事项
-
返回值: replaceChild
方法返回被替换的节点的引用。这可以用于在替换节点后进行进一步的操作或在其他地方重新插入节点。
// 获取父节点
var parentElement = document.getElementById('parentElement');
// 创建新节点
var newNode = document.createElement('div');
newNode.textContent = 'Updated content';
// 获取要替换的现有节点
var oldNode = document.getElementById('oldNode');
// 替换现有节点为新节点,并保存被替换的节点的引用
var replacedNode = parentElement.replaceChild(newNode, oldNode);
// 在其他地方重新插入被替换的节点
document.body.appendChild(replacedNode);
-
不存在的子节点: 如果尝试替换不存在的子节点,replaceChild
方法将抛出一个错误。因此,在使用 replaceChild
之前,最好检查一下要替换的节点是否存在。
// 获取父节点
var parentElement = document.getElementById('parentElement');
// 创建新节点
var newNode = document.createElement('div');
newNode.textContent = 'Updated content';
// 获取要替换的现有节点
var nonExistentNode = document.getElementById('nonExistentNode');
// 在替换之前检查节点是否存在
if (nonExistentNode) {
parentElement.replaceChild(newNode, nonExistentNode);
}
总体而言,replaceChild
提供了一种方便的方式来在 DOM 中动态替换子节点,以实现动态更新和交互。
5、DOM
核心api
——查找
传统方法
5.1 document.getElementById()
当调用 document.getElementById(id)
时,需要传入一个参数 id
,代表所要查找的元素的唯一标识符。
用法
var element = document.getElementById('yourElementId');
yourElementId
: 要查找元素的唯一标识符。
返回值
- 如果找到匹配的元素,返回对应的 DOM 元素对象。
- 如果未找到匹配的元素,返回
null
。
示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>getElementById 示例title>
head>
<body>
<div id="myDiv">
<p>This is a div with an id of "myDiv".p>
div>
<script>
// 获取具有 id 为 "myDiv" 的元素
var divElement = document.getElementById('myDiv');
// 修改元素的文本内容
divElement.textContent = 'Content updated using getElementById.';
// 修改元素的样式
divElement.style.backgroundColor = '#f0f0f0';
script>
body>
html>
在上述示例中,document.getElementById('myDiv')
查找具有 id
为 “myDiv” 的元素,然后通过 JavaScript 修改了该元素的文本内容和样式。
用途
-
操作特定元素: 通过元素的 id
属性,getElementById
允许开发者直接获取特定的元素,从而在 JavaScript 中进行操作。
// 获取页面上的按钮元素
var myButton = document.getElementById('myButton');
// 添加点击事件监听器
myButton.addEventListener('click', function() {
alert('Button clicked!');
});
-
动态更新页面内容: 使用 getElementById
可以在 JavaScript 中动态更新页面上特定元素的内容。
// 获取具有 id 为 "info" 的元素
var infoElement = document.getElementById('info');
// 更新元素的文本内容
infoElement.textContent = 'New information added dynamically.';
-
样式修改: 通过获取元素并使用 JavaScript 修改其样式,可以实现动态改变页面外观的效果。
// 获取具有 id 为 "header" 的元素
var headerElement = document.getElementById('header');
// 修改元素的样式
headerElement.style.color = 'blue';
注意事项
-
唯一性: HTML 规范要求每个页面中的 id
值应该是唯一的,确保元素具有唯一的标识符。
-
返回值: 如果未找到匹配的元素,getElementById
返回 null
。在使用返回值之前,应该始终检查是否为 null
,以防止在不存在该元素的情况下引发错误。
var element = document.getElementById('nonExistentElement');
if (element !== null) {
// 执行操作
} else {
console.error('Element not found.');
}
总体而言,document.getElementById
是一种常用的 DOM 操作方法,可用于通过元素的唯一标识符获取并操作特定的页面元素。
5.2 document.getElementsByClassName()
document.getElementsByClassName(className)
是 DOM 中的方法,用于获取包含指定类名的所有元素。这个方法返回一个 HTMLCollection
对象,该对象包含文档中所有具有指定类名的元素。
用法
var elements = document.getElementsByClassName('yourClassName');
yourClassName
: 要匹配的类名。
返回值
- 返回一个
HTMLCollection
对象,其中包含文档中所有具有指定类名的元素。如果没有找到匹配的元素,则返回一个空的 HTMLCollection
。
示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>getElementsByClassName 示例title>
<style>
.highlight {
color: red;
font-weight: bold;
}
style>
head>
<body>
<p class="highlight">This is a highlighted paragraph.p>
<p>This is a regular paragraph.p>
<p class="highlight">Another highlighted paragraph.p>
<script>
// 获取具有类名 "highlight" 的所有元素
var highlightedElements = document.getElementsByClassName('highlight');
// 在控制台中输出找到的元素数量
console.log('Found ' + highlightedElements.length + ' elements with class "highlight".');
// 遍历所有找到的元素并修改它们的文本内容
for (var i = 0; i < highlightedElements.length; i++) {
highlightedElements[i].textContent = 'Element ' + (i + 1);
}
script>
body>
html>
在上述示例中,document.getElementsByClassName('highlight')
获取所有具有类名 “highlight” 的元素,并在控制台中输出找到的元素数量。然后,通过遍历这些元素,修改了它们的文本内容。
用途
-
批量操作相似元素: getElementsByClassName
是一种方便的方式,用于获取文档中具有相似样式或特征的元素,并对它们进行批量操作。
// 获取所有具有类名 "card" 的元素
var cardElements = document.getElementsByClassName('card');
// 遍历所有卡片元素并添加点击事件监听器
for (var i = 0; i < cardElements.length; i++) {
cardElements[i].addEventListener('click', function() {
alert('Card clicked!');
});
}
-
动态更新元素样式: 可以使用 getElementsByClassName
获取一组具有相同类名的元素,然后通过 JavaScript 动态更新它们的样式。
// 获取所有具有类名 "highlight" 的元素
var highlightedElements = document.getElementsByClassName('highlight');
// 遍历并修改这些元素的样式
for (var i = 0; i < highlightedElements.length; i++) {
highlightedElements[i].style.backgroundColor = 'yellow';
}
注意事项
-
返回值类型: getElementsByClassName
返回的是一个 HTMLCollection,而不是数组。HTMLCollection 是一个动态的集合,会随着文档的变化而更新。如果需要使用数组方法,可以将 HTMLCollection 转换为数组。
var elementsArray = Array.from(document.getElementsByClassName('yourClassName'));
// 或者
var elementsArray = [...document.getElementsByClassName('yourClassName')];
-
性能注意: getElementsByClassName
返回的 HTMLCollection
是实时的,这意味着它会随着文档的变化而更新。在使用大量元素时,频繁调用这个方法可能会影响性能。如果只需获取一次类名相同的元素集合,考虑使用更现代的方法,如 document.querySelectorAll('.yourClassName')
。
-
直接写类名不需要加.
5.3 document.getElementsByTagName()
document.getElementsByTagName(tagName)
是 DOM 中的方法,用于获取指定标签名的所有元素。这个方法返回一个 HTMLCollection 对象,其中包含文档中所有具有指定标签名的元素。
用法
var elements = document.getElementsByTagName('yourTagName');
yourTagName
: 要匹配的标签名。
返回值
- 返回一个 HTMLCollection 对象,其中包含文档中所有具有指定标签名的元素。如果没有找到匹配的元素,则返回一个空的 HTMLCollection。
示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>getElementsByTagName 示例title>
head>
<body>
<p>This is a paragraph.p>
<div>This is a division.div>
<p>Another paragraph.p>
<script>
// 获取所有段落元素
var paragraphElements = document.getElementsByTagName('p');
// 在控制台中输出找到的元素数量
console.log('Found ' + paragraphElements.length + ' paragraph elements.');
// 遍历所有找到的段落元素并修改它们的文本内容
for (var i = 0; i < paragraphElements.length; i++) {
paragraphElements[i].textContent = 'Paragraph ' + (i + 1);
}
script>
body>
html>
在上述示例中,document.getElementsByTagName('p')
获取所有段落元素,并在控制台中输出找到的元素数量。然后,通过遍历这些元素,修改了它们的文本内容。
用途
-
批量操作相似元素: getElementsByTagName
是一种方便的方式,用于获取文档中具有相同标签名的元素,并对它们进行批量操作。
// 获取所有图片元素
var imgElements = document.getElementsByTagName('img');
// 遍历所有图片元素并添加点击事件监听器
for (var i = 0; i < imgElements.length; i++) {
imgElements[i].addEventListener('click', function() {
alert('Image clicked!');
});
}
-
动态更新元素属性: 可以使用 getElementsByTagName
获取一组具有相同标签名的元素,然后通过 JavaScript 动态更新它们的属性。
// 获取所有链接元素
var linkElements = document.getElementsByTagName('a');
// 遍历并修改这些链接元素的属性
for (var i = 0; i < linkElements.length; i++) {
linkElements[i].setAttribute('target', '_blank');
}
注意事项
-
返回值类型: getElementsByTagName
返回的是一个 HTMLCollection,而不是数组。HTMLCollection 是一个动态的集合,会随着文档的变化而更新。如果需要使用数组方法,可以将 HTMLCollection 转换为数组。
var elementsArray = Array.from(document.getElementsByTagName('yourTagName'));
// 或者
var elementsArray = [...document.getElementsByTagName('yourTagName')];
-
性能注意: getElementsByTagName
返回的 HTMLCollection 是实时的,这意味着它会随着文档的变化而更新。在使用大量元素时,频繁调用这个方法可能会影响性能。如果只需获取一次指定标签名的元素集合,考虑使用更现代的方法,如 document.querySelectorAll('yourTagName')
。
总体而言,document.getElementsByTagName
是一种用于获取具有指定标签名的元素集合的常见方法,适用于批量操作或动态更新属性的场景。
H5新方法
5.3 document.querySelector()
document.querySelector(selector)
是 DOM 中的方法,用于选择文档中匹配指定 CSS 选择器的第一个元素。如果找到匹配的元素,则返回该元素,否则返回 null
。
用法
var element = document.querySelector('yourSelector');
yourSelector
: 一个 CSS 选择器字符串,用于匹配要选择的元素。
返回值
- 返回文档中匹配选择器的第一个元素,如果没有找到匹配的元素,则返回
null
。
示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>querySelector 示例title>
<style>
.highlight {
background-color: yellow;
}
style>
head>
<body>
<p>This is a paragraph.p>
<div class="highlight">This is a highlighted div.div>
<p>Another paragraph.p>
<script>
// 获取第一个匹配到的段落元素
var firstParagraph = document.querySelector('p');
// 在控制台中输出匹配到的元素内容
console.log('First paragraph content:', firstParagraph.textContent);
// 获取匹配到的具有.highlight类的元素
var highlightedDiv = document.querySelector('.highlight');
// 在控制台中输出匹配到的元素内容
console.log('Highlighted div content:', highlightedDiv.textContent);
script>
body>
html>
在上述示例中,document.querySelector('p')
选择文档中的第一个段落元素,并输出其内容。同样,document.querySelector('.highlight')
选择文档中具有 .highlight
类的第一个元素,并输出其内容。
用途
-
选择单个元素: querySelector
主要用于选择文档中匹配指定 CSS 选择器的第一个元素。
// 获取文档中第一个段落元素
var firstParagraph = document.querySelector('p');
-
选择具有特定类的元素: 可以使用类选择器选择具有特定类的元素。
// 获取文档中具有.highlight类的第一个元素
var highlightedDiv = document.querySelector('.highlight');
-
选择具有特定 ID 的元素: 可以使用 ID 选择器选择具有特定 ID 的元素。
// 获取文档中具有#myElement ID的元素
var myElement = document.querySelector('#myElement');
-
选择符合更复杂条件的元素: 可以使用更复杂的 CSS 选择器来选择符合特定条件的元素。
// 获取文档中第一个段落元素中的第一个 strong 元素
var firstStrongInParagraph = document.querySelector('p strong');
注意事项
-
返回值: querySelector
返回的是文档中匹配选择器的第一个元素。如果需要选择所有匹配的元素,可以使用 document.querySelectorAll
。
// 获取文档中所有段落元素
var allParagraphs = document.querySelectorAll('p');
-
选择器语法: 选择器参数应该符合 CSS 选择器语法。选择器语法定义了一种描述文档中元素样式和结构的语言。
// 错误的选择器语法,可能导致选择失败
var invalidSelector = document.querySelector('p .highlight');
总体而言,document.querySelector
是一种强大而灵活的方法,用于选择文档中的元素,特别是在只关心第一个匹配元素时。
5.4 document.body
document.body
不是一个方法(function),而是一个属性(property)。它返回文档(document)的
元素,即 HTML 文档中
标签对应的 DOM 元素。
用法
var bodyElement = document.body;
返回值
- 返回文档的
元素。
示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>document.body 示例title>
head>
<body>
<h1>Hello, World!h1>
<p>This is a paragraph.p>
<script>
// 获取文档的 元素
var bodyElement = document.body;
// 在控制台中输出 元素的内容
console.log('Body content:', bodyElement.textContent);
script>
body>
html>
在上述示例中,document.body
用于获取文档的
元素,并通过 console.log
输出了其内容。
用途
-
访问
元素: document.body
用于直接访问文档的
元素,以便进行相关的 DOM 操作。
// 获取文档的 元素
var bodyElement = document.body;
// 对 元素进行操作
bodyElement.style.backgroundColor = 'lightgray';
-
动态操作页面内容: 通过
元素,你可以动态地向页面添加、删除或修改元素,实现对页面内容的动态更新。
// 获取文档的 元素
var bodyElement = document.body;
// 在 中添加新的段落元素
var newParagraph = document.createElement('p');
newParagraph.textContent = 'This is a dynamically added paragraph.';
bodyElement.appendChild(newParagraph);
注意事项
document.body
返回的是一个引用,因此对该引用的操作会直接影响文档中的
元素。在对
进行 DOM 操作时要小心,以免影响页面的整体结构和样式。
总体而言,document.body
属性是一个方便的方式,用于访问文档的
元素,从而实现对页面内容的操作。
5.5 document.documentElement
document.documentElement
是 JavaScript 中用于获取文档根元素的属性。在 HTML 文档中,根元素通常是
。通过访问 document.documentElement
,你可以获取对这个根元素的引用,并进行相应的操作。
用法
// 获取文档的根元素
var rootElement = document.documentElement;
// 示例:应用全局样式
rootElement.style.fontSize = '16px';
// 示例:操作文档的语言属性
rootElement.lang = 'en';
在上述示例中,我们首先通过 document.documentElement
获取文档的根元素,然后可以使用这个引用来应用全局样式或操作文档的属性,比如更改文档的语言属性。
注意事项
- 全局性操作: 因为
document.documentElement
提供了对整个文档根元素的引用,对其的操作会影响到整个文档,包括所有子元素。因此,在使用时需要谨慎,确保不会造成意外的影响。
// 不建议的操作:修改根元素的样式可能影响到整个文档
document.documentElement.style.backgroundColor = 'lightgray';
总之,document.documentElement
提供了一种方便的方式来访问文档的根元素,使你能够在整个文档范围内进行全局性的 JavaScript 操作。
5.6 document.querySelectorAll()
document.querySelectorAll()
是 JavaScript 中用于选择文档中多个元素的方法。它返回一个 NodeList
对象,该对象包含与指定的 CSS 选择器或选择器组匹配的所有元素。
用法
// 使用单个选择器
var elements = document.querySelectorAll('.example-class');
// 使用多个选择器
var multipleSelectors = document.querySelectorAll('.class1, .class2, #id');
// 使用后代选择器
var descendants = document.querySelectorAll('div p');
在上述示例中,我们通过 document.querySelectorAll()
分别选择了具有特定类名、多个选择器以及后代关系的元素。
返回值
document.querySelectorAll()
返回一个 NodeList
对象,该对象是一个类似数组的对象,包含了选中的元素。可以使用数组的方式或 forEach
方法遍历这个对象。
var elements = document.querySelectorAll('.example-class');
// 通过下标访问元素
var firstElement = elements[0];
// 使用 forEach 遍历
elements.forEach(function(element) {
console.log(element);
});
示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>querySelectorAll 示例title>
<style>
.example-class {
color: blue;
}
style>
head>
<body>
<div class="example-class">Element 1div>
<div class="example-class">Element 2div>
<p class="example-class">Element 3p>
<p>Not selectedp>
<script>
// 通过类名选择元素
var elements = document.querySelectorAll('.example-class');
// 遍历选中的元素
elements.forEach(function(element) {
console.log(element.textContent);
});
script>
body>
html>
在这个示例中,通过 .example-class
类名选择了所有拥有该类名的元素,并通过 JavaScript 遍历输出了它们的文本内容。
注意事项
- 静态集合:
NodeList
是一个静态集合,这意味着它会在查询时立即获取并存储匹配的元素,而不会动态更新。如果文档结构发生更改,NodeList
不会自动更新,需要重新查询以获取最新的元素集合。
// 静态集合示例
var elements = document.querySelectorAll('.example-class');
console.log(elements.length); // 输出匹配的元素数量
// 如果后续添加了新元素,elements 不会更新
var newElement = document.createElement('div');
newElement.className = 'example-class';
document.body.appendChild(newElement);
console.log(elements.length); // 仍然输出初始匹配的元素数量
总体而言,document.querySelectorAll()
提供了一种强大的选择元素的方式,允许你使用灵活的 CSS 选择器语法来匹配并操作文档中的多个元素。
利用节点获取元素
5.4parentNode
属性
语法
var parent = node.parentNode;
用法
parentNode
属性用于获取一个节点的父节点。
返回值
- 如果节点有父节点,返回一个表示父节点的对象。
- 如果节点没有父节点(例如根节点),返回
null
。
示例
var childNode = document.getElementById('child-element');
var parentNode = childNode.parentNode;
console.log(parentNode); // 获取 childNode 的父节点
使用场景
- 节点移动和操作: 通过
parentNode
,你可以获取节点的父节点,并进行节点的移动、删除或其他操作。
- DOM 遍历: 在处理复杂的文档结构时,
parentNode
是导航 DOM 树的有用工具。
原理
parentNode
属性通过连接 DOM 结构中节点的父子关系来工作。每个节点都有一个 parentNode
属性,它指向节点的直接父节点。当使用 parentNode
时,浏览器引擎会返回表示父节点的节点对象或 null
(如果节点没有父节点)。
完整示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>parentNode 示例title>
head>
<body>
<div id="parent">
<p id="child">我是子节点。p>
div>
<script>
var childNode = document.getElementById('child');
var parentNode = childNode.parentNode;
console.log(parentNode); // 输出:...
script>
body>
html>
在这个示例中,childNode
是一个
元素,而 parentNode
是包含它的 元素。通过 parentNode
,我们获取到了节点的父节点。
5.5 children
属性
语法
var childNodes = parentElement.children;
用法
children
属性用于获取一个元素节点的子元素节点集合。
返回值
返回一个表示元素的子元素节点的 HTMLCollection
对象。
示例
var parentElement = document.getElementById('parent');
var childNodes = parentElement.children;
for (var i = 0; i < childNodes.length; i++) {
console.log(childNodes[i]); // 遍历输出子元素节点
}
使用场景
- 遍历子元素节点: 使用
children
属性,你可以方便地遍历和操作一个元素的所有子元素节点。
- 获取特定子元素: 通过索引或其他属性,你可以获取
children
中的特定子元素。
原理
children
属性返回一个 HTMLCollection
对象,该对象是一个动态集合,包含了元素的所有子元素节点。这个集合是实时更新的,当 DOM 结构发生变化时,集合也会相应更新。
完整示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>children 属性示例title>
head>
<body>
<div id="parent">
<p>第一个子元素p>
<div>第二个子元素div>
<span>第三个子元素span>
div>
<script>
var parentElement = document.getElementById('parent');
var childNodes = parentElement.children;
for (var i = 0; i < childNodes.length; i++) {
console.log(childNodes[i]); // 遍历输出子元素节点
}
script>
body>
html>
在这个示例中,parentElement
是一个 元素,通过 children
属性,我们得到了它的所有子元素节点,并通过循环遍历输出了每个子元素节点。
5.6 previousElementSibling
属性
语法
var previousElement = element.previousElementSibling;
用法
previousElementSibling
属性用于获取一个元素节点在同一父元素下的前一个元素节点。
返回值
返回表示前一个元素节点的对象,如果没有前一个元素节点(即该元素是其父元素的第一个子元素),则返回 null
。
示例
var currentElement = document.getElementById('current-element');
var previousElement = currentElement.previousElementSibling;
console.log(previousElement); // 获取当前元素的前一个元素节点
使用场景
- 在同一父元素中导航: 通过
previousElementSibling
,你可以轻松地在同一父元素下导航到前一个元素节点。
- 动态样式修改: 在 DOM 操作中,有时你可能需要根据前一个元素的存在与否来进行样式或内容的动态修改。
原理
previousElementSibling
属性通过访问 DOM 结构中的节点关系来工作。这个属性返回表示同一父元素下前一个元素节点的对象,如果前一个元素节点不存在,则返回 null
。
完整示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>previousElementSibling 示例title>
head>
<body>
<div id="parent">
<p id="first-child">第一个子元素p>
<p id="current-element">当前元素p>
<p id="next-sibling">下一个兄弟元素p>
div>
<script>
var currentElement = document.getElementById('current-element');
var previousElement = currentElement.previousElementSibling;
console.log(previousElement); // 输出:第一个子元素
script>
body>
html>
在这个示例中,currentElement
是一个
元素,通过 previousElementSibling
属性,我们获取到了它在同一父元素下的前一个元素节点,并将其输出到控制台。
5.7nextElementSibling
属性
语法
var nextElement = element.nextElementSibling;
用法
nextElementSibling
属性用于获取一个元素节点在同一父元素下的后一个元素节点。
返回值
返回表示后一个元素节点的对象,如果没有后一个元素节点(即该元素是其父元素的最后一个子元素),则返回 null
。
示例
var currentElement = document.getElementById('current-element');
var nextElement = currentElement.nextElementSibling;
console.log(nextElement); // 获取当前元素的后一个元素节点
使用场景
- 在同一父元素中导航: 通过
nextElementSibling
,你可以轻松地在同一父元素下导航到后一个元素节点。
- 动态样式修改: 在 DOM 操作中,有时你可能需要根据后一个元素的存在与否来进行样式或内容的动态修改。
原理
nextElementSibling
属性通过访问 DOM 结构中的节点关系来工作。这个属性返回表示同一父元素下后一个元素节点的对象,如果后一个元素节点不存在,则返回 null
。
完整示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>nextElementSibling 示例title>
head>
<body>
<div id="parent">
<p id="previous-sibling">上一个兄弟元素p>
<p id="current-element">当前元素p>
<p id="last-child">最后一个子元素p>
div>
<script>
var currentElement = document.getElementById('current-element');
var nextElement = currentElement.nextElementSibling;
console.log(nextElement); // 输出:最后一个子元素
script>
body>
html>
在这个示例中,currentElement
是一个
元素,通过 nextElementSibling
属性,我们获取到了它在同一父元素下的后一个元素节点,并将其输出到控制台。
6、DOM
核心api
——修改
6.1 访问和修改的方法
由于获取的页面元素,本质上都是对象
,因此用访问和修改对象属性的方法,来访问和修改页面元素的属性
-
通过点语法:对象.属性名=‘属性值’
js
复制代码 img.src = './images/lyf.jpg'
-
通过中括号: 对象[‘属性名’]=‘属性值’
js
复制代码img['title'] = '我是李易峰'
6.2 常被修改的元素属性:src、href、tittle等
6.3 修改普通元素内容:innerText和innerHTML
- 相同点
- 都能获取
双标签
元素的内容
- 都能给
双标签
元素添加内容
- 不同点
- 获取内容时:innerText只能获取文本内容,innerHTML既能获取文本,也能获取标签
- 添加内容时:如果内容中有标签,innerText会把标签当做文本一起添加进去,而innerHTML会把标签
解析
出来,比如h3,innerHTML会把标签内容解析为h3的格式
6.4 修改表单的属性
- 获取表单元素(单标签)的文本:对象名.value
- 一些表单属性:disabled(是否禁用)、checked(单复选框是否选中)、selected(下拉菜单是否选中),这些属性,在js中是写上就代表使用了,因此修改的时候,赋值为true 或false即可
6.5 修改元素样式
- document.style.样式名,如box.style.width=‘300px’
6.6 修改元素的类名
6.6.1 传统方法修改类名
- className,如box.className=‘.red’
6.6.2 H5新增的操作元素类的方法——classList
为什么有这个新增的方法?
- 传统的className方法,添加和删除的操作都非常不方便
- 添加的时候,如果直接用等号,会覆盖原来的样式;如果用加等,可以一直赋值相同的类名,但样式没有任何变化,
- 删除的时候,如果用赋值为原值的方法进行删除,会把后来添加的所有样式,都删除;如果用replaca替换的方法进行删除,在行内样式中会产生很多空格,而且,如果有重复的样式名,只能删除一个
6.6,2.1 classList.add()
语法
element.classList.add(className1, className2, ...);
参数
className1, className2, ...
: 一个或多个字符串参数,表示要添加到元素的类名。
用法
classList.add()
方法用于向元素的类列表中添加一个或多个类名。如果某个类名已经存在,它将被忽略,不会导致重复添加。
返回值
该方法没有返回值。
示例
var element = document.getElementById('myElement');
element.classList.add('active', 'highlight');
使用场景
- 动态添加样式: 在 JavaScript 中,通过
classList.add()
方法可以在运行时根据特定条件动态地添加样式。
- 交互式用户界面: 在响应用户交互时,根据用户的操作添加或移除类名,以改变元素的外观或行为。
原理
classList
是一个包含元素所有类名的只读属性。classList.add()
方法通过修改元素的 classList
属性,实现向元素的类列表中添加类名。如果指定的类名已存在,则忽略该类名,不会造成重复。
完整示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>classList.add() 示例title>
<style>
.active {
color: red;
}
.highlight {
font-weight: bold;
}
style>
head>
<body>
<p id="myElement">这是一个段落。p>
<script>
var element = document.getElementById('myElement');
element.classList.add('active', 'highlight');
script>
body>
html>
在这个示例中,classList.add()
方法用于向一个段落元素添加了两个类名:active
和 highlight
,从而应用了相应的样式。
6.6.2.2classList.remove()
语法
element.classList.remove(className1, className2, ...);
参数
className1, className2, ...
: 一个或多个字符串参数,表示要从元素的类列表中移除的类名。
用法
classList.remove()
方法用于从元素的类列表中移除一个或多个类名。如果某个类名不存在,它将被忽略。
返回值
该方法没有返回值。
示例
var element = document.getElementById('myElement');
element.classList.remove('active', 'highlight');
使用场景
- 动态修改样式: 在 JavaScript 中,通过
classList.remove()
方法可以在运行时根据特定条件动态地移除样式。
- 交互式用户界面: 在响应用户交互时,根据用户的操作移除或添加类名,以改变元素的外观或行为。
原理
classList
是一个包含元素所有类名的只读属性。classList.remove()
方法通过修改元素的 classList
属性,实现从元素的类列表中移除类名。如果指定的类名不存在,则忽略该类名。
注意事项
-
参数顺序: classList.remove()
方法的参数是一个或多个要移除的类名,按照参数的顺序依次移除。可以一次性移除多个类名。
var element = document.getElementById('myElement');
element.classList.remove('class1', 'class2', 'class3');
-
不存在的类名: 如果指定的类名在元素的类列表中不存在,classList.remove()
方法会忽略它,而不会引发错误。
var element = document.getElementById('myElement');
element.classList.remove('nonexistent-class');
-
动态应用和移除: classList
方法通常用于动态地应用和移除样式。这对于响应用户交互、动画效果等场景非常有用。
var element = document.getElementById('myElement');
// 添加类名
element.classList.add('active');
// 移除类名
element.classList.remove('inactive');
-
兼容性: classList
属性和相关方法在大多数现代浏览器中得到了良好的支持。但在一些较老的浏览器版本中可能存在一些兼容性问题。在使用时,可以考虑使用 polyfill 或其他解决方案来提供兼容性支持。
// 例子:classList 兼容性 polyfill
if (!("classList" in document.documentElement)) {
Object.defineProperty(HTMLElement.prototype, 'classList', {
get: function() {
var self = this;
function update(fn) {
return function(value) {
var classes = self.className.split(/\s+/g),
index = classes.indexOf(value);
fn(classes, index, value);
self.className = classes.join(" ");
};
}
return {
add: update(function(classes, index, value) {
~index || classes.push(value);
}),
remove: update(function(classes, index) {
~index && classes.splice(index, 1);
}),
toggle: update(function(classes, index, value) {
~index ? classes.splice(index, 1) : classes.push(value);
}),
contains: function(value) {
return !!~self.className.split(/\s+/g).indexOf(value);
}
};
}
});
}
总体而言,classList.remove()
方法是一个方便的 DOM 操作方法,可用于动态地管理元素的类名,从而实现样式的动态修改。
完整示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>classList.remove() 示例title>
<style>
.active {
color: red;
}
.highlight {
font-weight: bold;
}
style>
head>
<body>
<p id="myElement" class="active highlight">这是一个段落。p>
<script>
var element = document.getElementById('myElement');
element.classList.remove('active', 'highlight');
script>
body>
html>
在这个示例中,classList.remove()
方法用于从一个段落元素中移除了两个类名:active
和 highlight
,从而取消了相应的样式。
6.6.2.3 classList.toogle()
语法
var result = element.classList.toggle(className, force);
参数
className
: 要切换的类名。
force
(可选): 一个布尔值,表示是否强制添加或移除类名。如果为 true
,则强制添加类名;如果为 false
,则强制移除类名。默认情况下,会在存在时移除,不存在时添加。
返回值
- 如果成功添加了类名,返回
true
。
- 如果成功移除了类名,返回
false
。
- 如果未指定
force
参数,并且类名已存在,则移除类名并返回 false
;如果类名不存在,则添加类名并返回 true
。
示例
var element = document.getElementById('myElement');
// 切换类名
var result = element.classList.toggle('active');
console.log(result); // 返回 true 或 false,表示是否添加或移除了类名
使用场景
- 动态切换样式: 在 JavaScript 中,通过
classList.toggle()
方法可以在运行时根据条件动态地切换元素的类名,实现样式的动态切换。
- 交互式用户界面: 在响应用户点击或其他交互操作时,根据当前状态切换类名,以改变元素的外观或行为。
原理
classList.toggle()
方法用于在元素的类列表中添加或移除一个类名。如果指定的类名已存在,则移除它;如果不存在,则添加它。通过设置 force
参数,可以强制添加或移除类名。
注意事项
-
force
参数使用: 如果使用了 force
参数,注意该参数的值。当 force
为 true
时,将强制添加指定的类名,而当 force
为 false
时,将强制移除指定的类名。默认情况下,未提供 force
参数,此时方法会根据类名的存在与否进行切换。
var element = document.getElementById('myElement');
// 强制添加类名
element.classList.toggle('active', true);
// 强制移除类名
element.classList.toggle('active', false);
-
返回值的理解: classList.toggle()
方法的返回值表示是否添加或移除了类名。返回 true
表示添加了类名,返回 false
表示移除了类名。这可以根据返回值来判断类名的最终状态。
var element = document.getElementById('myElement');
// 切换类名,并获取切换后的状态
var isClassAdded = element.classList.toggle('active');
console.log(isClassAdded); // 返回 true 或 false,表示是否添加或移除了类名
-
动态应用和移除: classList.toggle()
方法通常用于动态地应用和移除样式。这对于响应用户交互、动画效果等场景非常有用。
var element = document.getElementById('myElement');
// 切换类名,根据条件动态修改样式
element.classList.toggle('highlight', shouldHighlight);
-
兼容性: classList
属性和相关方法在大多数现代浏览器中得到了良好的支持。然而,在一些较老的浏览器版本中可能存在一些兼容性问题。在使用时,可以考虑使用 polyfill 或其他解决方案来提供兼容性支持。
完整示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>classList.toggle() 示例title>
<style>
.active {
color: red;
}
style>
head>
<body>
<p id="myElement">这是一个段落。p>
<script>
var element = document.getElementById('myElement');
// 切换类名
var result = element.classList.toggle('active');
console.log(result); // 返回 true 或 false,表示是否添加或移除了类名
script>
body>
html>
在这个示例中,classList.toggle()
方法用于在段落元素的类列表中切换 active
类名。根据 active
类名的存在与否,方法的返回值为 true
或 false
,表示是否添加或移除了类名。
6.6.2.4 classList.contains()
语法
var containsClass = element.classList.contains(className);
参数
className
: 要检查的类名。
返回值
- 如果元素的类列表中包含指定的类名,返回
true
。
- 如果元素的类列表中不包含指定的类名,返回
false
。
示例
var element = document.getElementById('myElement');
var containsClass = element.classList.contains('active');
console.log(containsClass); // 返回 true 或 false,表示是否包含指定的类名
使用场景
- 检查类名存在性: 在 JavaScript 中,通过
classList.contains()
方法可以在运行时检查元素的类列表中是否包含指定的类名。
- 条件性样式应用: 在动态应用样式或处理交互时,可以使用此方法检查类名是否存在,从而决定应该执行何种操作。
原理
classList.contains()
方法用于检查元素的类列表是否包含指定的类名。如果类名存在,返回 true
;如果类名不存在,返回 false
。
完整示例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>classList.contains() 示例title>
head>
<body>
<div id="myElement" class="active">这是一个元素。div>
<script>
var element = document.getElementById('myElement');
// 检查类名是否存在
var containsClass = element.classList.contains('active');
console.log(containsClass); // 返回 true 或 false,表示是否包含指定的类名
script>
body>
html>
在这个示例中,classList.contains()
方法用于检查一个 div
元素的类列表是否包含 active
类名。根据结果,将返回 true
或 false
。
7 DOM
核心api
——属性操作
7.1传统操作自定义属性的方法
7.1.1 setAttribute()
setAttribute
是 JavaScript 中用于设置元素属性的方法。通过这个方法,你可以动态地向 HTML 元素添加、修改或删除属性。
语法
element.setAttribute(attributeName, attributeValue);
element
: 要操作的 HTML 元素。
attributeName
: 要设置的属性的名称。
attributeValue
: 要设置的属性的值。
示例
// 获取元素
var element = document.getElementById('myElement');
// 设置自定义属性
element.setAttribute('data-user-id', '123');
element.setAttribute('data-role', 'admin');
使用场景
-
动态设置属性: setAttribute
主要用于在 JavaScript 中动态设置元素的属性。这对于根据用户操作或其他条件更改元素的属性非常有用。
// 根据用户选择动态设置链接地址
var linkElement = document.getElementById('myLink');
linkElement.setAttribute('href', 'https://example.com');
-
设置自定义数据属性: setAttribute
可以用于设置自定义数据属性,这在存储元素相关的数据时很有用。
// 设置自定义数据属性
var element = document.getElementById('myElement');
element.setAttribute('data-custom-info', 'some information');
-
动态修改元素属性: 如果你希望根据特定条件动态更改元素的属性,setAttribute
提供了一种灵活的方式。
// 根据条件动态设置或移除属性
var element = document.getElementById('myElement');
if (someCondition) {
element.setAttribute('disabled', 'true');
} else {
element.removeAttribute('disabled');
}
注意事项
-
对于标准属性的设置: 对于标准 HTML 属性,直接使用元素对象的属性赋值方式可能更为简洁。例如,element.src = 'some-source';
。
-
事件处理程序: 对于事件处理程序,最好使用 addEventListener
方法,而不是通过 setAttribute
设置 'onclick'
等属性。
// 不推荐
element.setAttribute('onclick', 'myFunction()');
// 推荐
element.addEventListener('click', myFunction);
- 兼容性:
setAttribute
方法在大多数现代浏览器中得到了良好的支持。但在一些较老的浏览器版本中可能存在一些兼容性问题。在使用时,可以考虑使用 polyfill 或其他解决方案来提供兼容性支持。
7.1.2 getAttibute()
getAttribute
是 JavaScript 中用于获取元素属性值的方法。通过这个方法,你可以检索元素的任何属性的当前值。
语法
var attributeValue = element.getAttribute(attributeName);
element
: 要操作的 HTML 元素。
attributeName
: 要获取值的属性的名称。
示例
// 获取元素
var element = document.getElementById('myElement');
// 获取自定义属性值
var userId = element.getAttribute('data-user-id');
var role = element.getAttribute('data-role');
使用场景
-
获取自定义属性值: getAttribute
主要用于获取元素的属性值,特别适用于自定义数据属性。
// 获取自定义数据属性值
var element = document.getElementById('myElement');
var customInfo = element.getAttribute('data-custom-info');
-
动态检查属性值: 你可以使用 getAttribute
来动态检查元素的某个属性是否存在,并获取其值。
// 动态检查并获取属性值
var element = document.getElementById('myElement');
var srcValue = element.getAttribute('src');
if (srcValue) {
console.log('元素具有 src 属性,值为: ' + srcValue);
} else {
console.log('元素没有 src 属性。');
}
-
获取元素属性: getAttribute
可以用于获取元素的任何属性,不仅仅是自定义属性。
// 获取元素的某个属性值
var element = document.getElementById('myElement');
var hrefValue = element.getAttribute('href');
注意事项
-
返回值: getAttribute
的返回值是字符串或 null
。如果指定的属性不存在,则返回 null
。
// 获取不存在的属性值
var element = document.getElementById('myElement');
var nonExistentValue = element.getAttribute('non-existent-attribute');
console.log(nonExistentValue); // 输出 null
-
对于标准属性的获取: 对于标准 HTML 属性,通常更推荐直接使用元素对象的属性来获取值。例如,element.src
。
-
兼容性: getAttribute
方法在大多数现代浏览器中得到了良好的支持。但在一些较老的浏览器版本中可能存在一些兼容性问题。在使用时,可以考虑使用 polyfill 或其他解决方案来提供兼容性支持。
7.1.3 removeAttibute()
removeAttribute
是 JavaScript 中用于移除元素属性的方法。通过这个方法,你可以动态地从 HTML 元素中删除指定的属性。
语法
element.removeAttribute(attributeName);
element
: 要操作的 HTML 元素。
attributeName
: 要移除的属性的名称。
示例
// 获取元素
var element = document.getElementById('myElement');
// 移除自定义属性
element.removeAttribute('data-user-id');
element.removeAttribute('data-role');
使用场景
-
移除自定义属性: removeAttribute
主要用于从元素中移除指定的属性,特别适用于自定义数据属性。
// 移除自定义数据属性
var element = document.getElementById('myElement');
element.removeAttribute('data-custom-info');
-
动态修改元素属性: 你可以使用 removeAttribute
来动态地修改元素的某个属性。
// 根据条件动态移除属性
var element = document.getElementById('myElement');
if (someCondition) {
element.removeAttribute('disabled');
}
-
清除元素属性: removeAttribute
可以用于清除元素的任何属性,不仅仅是自定义属性。
// 移除元素的某个属性
var element = document.getElementById('myElement');
element.removeAttribute('href');
注意事项
-
对于标准属性的移除: removeAttribute
可以用于移除任何属性,包括标准 HTML 属性。但对于一些特定的标准属性,最好直接使用对应的属性赋值方式,例如 element.src = '';
。
-
动态检查属性并移除: 可以在使用 removeAttribute
之前先使用 hasAttribute
方法检查属性是否存在。
// 动态检查并移除属性
var element = document.getElementById('myElement');
if (element.hasAttribute('data-custom-info')) {
element.removeAttribute('data-custom-info');
}
-
兼容性: removeAttribute
方法在大多数现代浏览器中得到了良好的支持。但在一些较老的浏览器版本中可能存在一些兼容性问题。在使用时,可以考虑使用 polyfill 或其他解决方案来提供兼容性支持。
7.1.4点语法
只能拿到html中自带的属性,不能拿到自定义属性
注意:以上方法,只能操作单个属性,如果想将自定义属性,全部取出,就很麻烦,因此,H5引入了新的操作自定义属性的方法,即dateset()
7.2 H5新增的操作自定义属性的方法
- 自定义属性写法规范:以用data-开头,方便识别哪些是自定义的属性
- 方法:元素.dataset
- 它是一个对象,可以获取所有以data-开头的自定义的属性
- 获取单个属性,用元素.dataset.属性名
- 设置元素属性,元素.dataset.属性名 = 数据
案例
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>自定义属性和dataset示例title>
<style>
.highlight {
color: red;
font-weight: bold;
}
style>
head>
<body>
<div id="myElement" data-user-id="123" data-role="admin">用户信息div>
<script>
// 获取示例元素
var element = document.getElementById('myElement');
// 通过 dataset 获取所有自定义属性
console.log('所有自定义属性:', element.dataset);
// 获取单个属性
var userId = element.dataset.userId;
var role = element.dataset.role;
console.log('用户ID:', userId);
console.log('角色:', role);
// 设置新的属性值
element.dataset.newAttribute = 'new value';
// 动态改变样式
if (userId === '123' && role === 'admin') {
element.classList.add('highlight');
}
script>
body>
html>
8 DOM
核心api
——事件操作
事件:就是用户与页面的交互,用户做了什么,页面做了什么回应
1、什么是事件对象?
- 其实就是一个对象。里面包含了
事件触发时
的一些信息,比如,是否按了alt键、鼠标点击的位置等
2、事件分类:0级事件和2级事件
- 0级事件:
- 用on开头,比如onclick;0级事件是DOM初稿中的方法
- 删除事件:对象.οnclick=null
- 2级事件:第二版DOM中的新方法
- 添加事件:对象.addEventListener(‘事件名’,function(){})
- 删除事件:对象.removeEventListener(‘事件名’, function(){})
- 删除时,用哪种方法添加的事件,就用哪种方式删除
- 匿名函数添加的事件,不能删除
3、事件三要素
-
事件源:真正触发事件的元素
- 获取事件源:e.target
-
事件类型
-
鼠标事件:
-
鼠标点击:click
-
鼠标双击:dblclick
-
鼠标移入:mouseover
-
鼠标移出:mouseout
-
鼠标按下:mousedown
-
鼠标弹起:mouseup
-
H5中的鼠标拖拽事件
- 元素默认不可拖拽,要加拖拽属性,才能拖拽,即draggable=‘true’
- 拖拽事件:
- 给被拖拽的元素加的事件:dragstart(拖拽开始)、drag(拖拽中)、dragend(拖拽结束事件)
- 给容器检测添加的事件:dragenter(拖拽进入事件)、dragleave(拖拽离开事件)
- 拖拽悬停事件:dragover
- 在容器范围内,鼠标拖拽并悬停,就会一直触发
- 它的默认行为是禁止被拖放进来
- 拖放事件:drop
- 在容器范围内,且松手
- 默认不触发,想触发,要先用dragover,阻止拖拽悬停的默认行为
-
焦点事件:
- 获得焦点:focus
- 失去焦点:blur
-
键盘事件:
- 键盘按下:keydown和keypress,常用keydown
- 键盘弹起:keyup,与keydown是一对,不区分大小写,不过滤功能键
-
响应程序:就是做了什么回应,一般是个函数
4、事件流
定义:事件触发时会经历从上到下,再从下到上的流动过程
- 事件流的三个阶段:
- 捕获阶段:从上到下,需要写代码调用
- 目标阶段:当前被触发的事件
- 冒泡阶段:从下往上,默认存在
5、事件流的应用——事件委托
- 什么是事件委托?
就是把事件交给其他元素来处理,即把事件绑定给其他元素,一般是父元素
- 为什么要委托?
主要是为了减少事件的绑定的次数,提高运行性能。
比如说,一个ul中有很多li,如果想点击每个li,就弹出这个li的内容,那传统的方法是,要遍历这个ul,找到每个li,给每个li添加点击事件,这样一方面会绑定很多事件,另一方面会降低运行性能;另外,如果后续这个ul中添加了很多新的li,那新增的li,是不会有点击事件的,因为,在给每个li添加事件时,获取的是当时ul中所有的li,后来新增的,不包含在内。
这种情况,就可以采用事件委托
的方法,把这个点击事件,绑定给li的父亲ul。借用事件冒泡
的优势,点击li的时候,li没有事件,会冒泡给父亲ul,ul再执行事件,显示每个事件源
的innerText即可。
-
事件委托的好处?
由此,可以看出,事件委托主要有两大好处:
- 减少事件的绑定的次数
- 让不管是老元素,还是后续新增的元素,同样具有事件
6、关于坐标系的使用场景
很多小伙伴在学习JS的时候,经常将e.pageX、e.screenX、e.clientX等概念,与三大家族混淆,不知道它们的区别及具体使用场景,在此做一个简要小结:
7.1、事件
里的坐标系:e.pageX、e.screenX、e.clientX
顾名思义,这些坐标系是用在事件里的,获取的是事件中鼠标的位置(坐标)
。我们都知道,事件
是用户在页面上做的一些操作(如鼠标点击、键盘按下等)后,页面给出的一些响应程序。事件中包含事件对象
,即保存了事件触发时的一些信息。
想要获取事件里的信息,需要在事件触发的函数(如onclick)内写一个形参,一般用e、ev、event等,这样,再触发的事件里,就可以用e.来获取事件触发时的一些信息。
因此,e.pageX、e.screenX、e.clientX这些,其实都是事件对象中的方法
, 主要作用是,获取事件内,鼠标
的一些位置信息,如点击的时候,鼠标距离【页面】的距离(e.pageX、e.pageY)、鼠标距离【可视区】的距离(e.clientX、e.clientY)、鼠标距离【屏幕】的距离(e.screenX、e.screenY)
7.2、给元素
使用的坐标系:三大家族
与上述事件内的坐标系不同,三大家族系列,不是给事件对象用的,而是给元素自己
用的,获取的是元素自己相对于页面(父盒子)、可视区和被卷去的距离,具体区别详见下图:
如,是否按了alt键、鼠标点击的位置等
2、事件分类:0级事件和2级事件
- 0级事件:
- 用on开头,比如onclick;0级事件是DOM初稿中的方法
- 删除事件:对象.οnclick=null
- 2级事件:第二版DOM中的新方法
- 添加事件:对象.addEventListener(‘事件名’,function(){})
- 删除事件:对象.removeEventListener(‘事件名’, function(){})
- 删除时,用哪种方法添加的事件,就用哪种方式删除
- 匿名函数添加的事件,不能删除
3、事件三要素
-
事件源:真正触发事件的元素
- 获取事件源:e.target
-
事件类型
-
鼠标事件:
-
鼠标点击:click
-
鼠标双击:dblclick
-
鼠标移入:mouseover
-
鼠标移出:mouseout
-
鼠标按下:mousedown
-
鼠标弹起:mouseup
-
H5中的鼠标拖拽事件
- 元素默认不可拖拽,要加拖拽属性,才能拖拽,即draggable=‘true’
- 拖拽事件:
- 给被拖拽的元素加的事件:dragstart(拖拽开始)、drag(拖拽中)、dragend(拖拽结束事件)
- 给容器检测添加的事件:dragenter(拖拽进入事件)、dragleave(拖拽离开事件)
- 拖拽悬停事件:dragover
- 在容器范围内,鼠标拖拽并悬停,就会一直触发
- 它的默认行为是禁止被拖放进来
- 拖放事件:drop
- 在容器范围内,且松手
- 默认不触发,想触发,要先用dragover,阻止拖拽悬停的默认行为
-
焦点事件:
- 获得焦点:focus
- 失去焦点:blur
-
键盘事件:
- 键盘按下:keydown和keypress,常用keydown
- 键盘弹起:keyup,与keydown是一对,不区分大小写,不过滤功能键
-
响应程序:就是做了什么回应,一般是个函数
4、事件流
定义:事件触发时会经历从上到下,再从下到上的流动过程
- 事件流的三个阶段:
- 捕获阶段:从上到下,需要写代码调用
- 目标阶段:当前被触发的事件
- 冒泡阶段:从下往上,默认存在
5、事件流的应用——事件委托
- 什么是事件委托?
就是把事件交给其他元素来处理,即把事件绑定给其他元素,一般是父元素
- 为什么要委托?
主要是为了减少事件的绑定的次数,提高运行性能。
比如说,一个ul中有很多li,如果想点击每个li,就弹出这个li的内容,那传统的方法是,要遍历这个ul,找到每个li,给每个li添加点击事件,这样一方面会绑定很多事件,另一方面会降低运行性能;另外,如果后续这个ul中添加了很多新的li,那新增的li,是不会有点击事件的,因为,在给每个li添加事件时,获取的是当时ul中所有的li,后来新增的,不包含在内。
这种情况,就可以采用事件委托
的方法,把这个点击事件,绑定给li的父亲ul。借用事件冒泡
的优势,点击li的时候,li没有事件,会冒泡给父亲ul,ul再执行事件,显示每个事件源
的innerText即可。
-
事件委托的好处?
由此,可以看出,事件委托主要有两大好处:
- 减少事件的绑定的次数
- 让不管是老元素,还是后续新增的元素,同样具有事件
6、关于坐标系的使用场景
很多小伙伴在学习JS的时候,经常将e.pageX、e.screenX、e.clientX等概念,与三大家族混淆,不知道它们的区别及具体使用场景,在此做一个简要小结:
7.1、事件
里的坐标系:e.pageX、e.screenX、e.clientX
顾名思义,这些坐标系是用在事件里的,获取的是事件中鼠标的位置(坐标)
。我们都知道,事件
是用户在页面上做的一些操作(如鼠标点击、键盘按下等)后,页面给出的一些响应程序。事件中包含事件对象
,即保存了事件触发时的一些信息。
想要获取事件里的信息,需要在事件触发的函数(如onclick)内写一个形参,一般用e、ev、event等,这样,再触发的事件里,就可以用e.来获取事件触发时的一些信息。
因此,e.pageX、e.screenX、e.clientX这些,其实都是事件对象中的方法
, 主要作用是,获取事件内,鼠标
的一些位置信息,如点击的时候,鼠标距离【页面】的距离(e.pageX、e.pageY)、鼠标距离【可视区】的距离(e.clientX、e.clientY)、鼠标距离【屏幕】的距离(e.screenX、e.screenY)
7.2、给元素
使用的坐标系:三大家族
与上述事件内的坐标系不同,三大家族系列,不是给事件对象用的,而是给元素自己
用的,获取的是元素自己相对于页面(父盒子)、可视区和被卷去的距离,具体区别详见下图: [外链图片转存中…(img-Ngy3JdM9-1706777902131)]