Skip to content

DOM 元素

DOM 元素的概念

DOM 元素是指 HTML 文档中的标签(如 <div><p><a> 等)在 DOM 树中的表示。每个 DOM 元素都是一个对象,具有属性和方法,用于操作元素的内容、属性和样式。

访问 DOM 元素

1. 通过 ID 访问

使用 getElementById() 方法通过元素的 ID 获取元素:

javascript
const element = document.getElementById("myElement");
console.log(element); // 输出: <div id="myElement">...</div>

2. 通过类名访问

使用 getElementsByClassName() 方法通过元素的类名获取元素集合:

javascript
const elements = document.getElementsByClassName("myClass");
console.log(elements); // 输出: HTMLCollection [div.myClass, p.myClass, ...]
console.log(elements.length); // 输出: 元素数量

// 遍历元素集合
for (let i = 0; i < elements.length; i++) {
  console.log(elements[i]);
}

// 转换为数组后使用 forEach
Array.from(elements).forEach((element) => {
  console.log(element);
});

3. 通过标签名访问

使用 getElementsByTagName() 方法通过元素的标签名获取元素集合:

javascript
const paragraphs = document.getElementsByTagName("p");
console.log(paragraphs); // 输出: HTMLCollection [p, p, ...]
console.log(paragraphs.length); // 输出: 段落数量

// 遍历元素集合
for (let i = 0; i < paragraphs.length; i++) {
  console.log(paragraphs[i]);
}

4. 通过 CSS 选择器访问

querySelector()

querySelector() 方法返回第一个匹配指定 CSS 选择器的元素:

javascript
const element = document.querySelector("#myElement");
console.log(element); // 输出: <div id="myElement">...</div>

const firstParagraph = document.querySelector("p");
console.log(firstParagraph); // 输出: 第一个 <p> 元素

const elementWithClass = document.querySelector(".myClass");
console.log(elementWithClass); // 输出: 第一个带有 myClass 类的元素

const nestedElement = document.querySelector("#container .item");
console.log(nestedElement); // 输出: #container 中第一个带有 item 类的元素

querySelectorAll()

querySelectorAll() 方法返回所有匹配指定 CSS 选择器的元素:

javascript
const elements = document.querySelectorAll(".myClass");
console.log(elements); // 输出: NodeList [div.myClass, p.myClass, ...]
console.log(elements.length); // 输出: 元素数量

// 遍历 NodeList
elements.forEach((element) => {
  console.log(element);
});

// 使用 for 循环遍历
for (let i = 0; i < elements.length; i++) {
  console.log(elements[i]);
}

5. 通过关系访问

通过元素之间的关系访问其他元素:

父元素

javascript
const element = document.getElementById("child");
const parent = element.parentElement;
console.log(parent); // 输出: 父元素

子元素

javascript
const parent = document.getElementById("parent");

// 获取所有子元素
const children = parent.children;
console.log(children); // 输出: HTMLCollection [子元素1, 子元素2, ...]

// 获取第一个子元素
const firstChild = parent.firstElementChild;
console.log(firstChild); // 输出: 第一个子元素

// 获取最后一个子元素
const lastChild = parent.lastElementChild;
console.log(lastChild); // 输出: 最后一个子元素

兄弟元素

javascript
const element = document.getElementById("middle");

// 获取前一个兄弟元素
const previousSibling = element.previousElementSibling;
console.log(previousSibling); // 输出: 前一个兄弟元素

// 获取后一个兄弟元素
const nextSibling = element.nextElementSibling;
console.log(nextSibling); // 输出: 后一个兄弟元素

创建和插入 DOM 元素

1. 创建元素

使用 createElement() 方法创建新元素:

javascript
// 创建新元素
const newDiv = document.createElement("div");

// 设置属性
newDiv.id = "newDiv";
newDiv.className = "container";
newDiv.setAttribute("title", "新元素");

// 设置内容
newDiv.textContent = "新创建的元素";

// 添加子元素
const newP = document.createElement("p");
newP.textContent = "新段落";
newDiv.appendChild(newP);

// 添加到文档
const parent = document.getElementById("parent");
parent.appendChild(newDiv);

2. 创建文本节点

使用 createTextNode() 方法创建新文本节点:

javascript
// 创建文本节点
const textNode = document.createTextNode("新文本");

// 添加到元素
const element = document.getElementById("myElement");
element.appendChild(textNode);

3. 插入元素

appendChild()

appendChild() 方法用于将元素添加到父元素的末尾:

javascript
const parent = document.getElementById("parent");
const newElement = document.createElement("div");
newElement.textContent = "新元素";

// 添加到末尾
parent.appendChild(newElement);

insertBefore()

insertBefore() 方法用于在指定元素前插入新元素:

javascript
const parent = document.getElementById("parent");
const referenceElement = document.getElementById("reference");
const newElement = document.createElement("div");
newElement.textContent = "新元素";

// 在参考元素前插入
parent.insertBefore(newElement, referenceElement);

// 在第一个子元素前插入
parent.insertBefore(newElement, parent.firstElementChild);

// 在末尾插入(与 appendChild 相同)
parent.insertBefore(newElement, null);

insertAdjacentElement()

insertAdjacentElement() 方法用于在指定位置插入元素:

javascript
const element = document.getElementById("myElement");
const newElement = document.createElement("div");
newElement.textContent = "新元素";

// 在元素前插入
element.insertAdjacentElement("beforebegin", newElement);

// 在元素内开头插入
element.insertAdjacentElement("afterbegin", newElement);

// 在元素内结尾插入
element.insertAdjacentElement("beforeend", newElement);

// 在元素后插入
element.insertAdjacentElement("afterend", newElement);

insertAdjacentHTML()

insertAdjacentHTML() 方法用于在指定位置插入 HTML 字符串:

javascript
const element = document.getElementById("myElement");

// 在元素前插入
element.insertAdjacentHTML("beforebegin", "<div>元素前</div>");

// 在元素内开头插入
element.insertAdjacentHTML("afterbegin", "<div>元素内开头</div>");

// 在元素内结尾插入
element.insertAdjacentHTML("beforeend", "<div>元素内结尾</div>");

// 在元素后插入
element.insertAdjacentHTML("afterend", "<div>元素后</div>");

删除和替换 DOM 元素

1. 删除元素

removeChild()

removeChild() 方法用于从父元素中移除子元素:

javascript
const parent = document.getElementById("parent");
const child = document.getElementById("child");

// 移除子元素
parent.removeChild(child);

remove()

remove() 方法用于直接移除元素:

javascript
const element = document.getElementById("myElement");

// 移除元素
element.remove();

2. 替换元素

replaceChild()

replaceChild() 方法用于用新元素替换旧元素:

javascript
const parent = document.getElementById("parent");
const oldElement = document.getElementById("old");
const newElement = document.createElement("div");
newElement.textContent = "新元素";

// 替换元素
parent.replaceChild(newElement, oldElement);

replaceWith()

replaceWith() 方法用于直接替换元素:

javascript
const oldElement = document.getElementById("old");
const newElement = document.createElement("div");
newElement.textContent = "新元素";

// 替换元素
oldElement.replaceWith(newElement);

修改 DOM 元素

1. 修改属性

setAttribute()

setAttribute() 方法用于设置元素的属性:

javascript
const element = document.getElementById("myElement");

// 设置属性
element.setAttribute("class", "newClass");
element.setAttribute("disabled", "disabled");
element.setAttribute("data-value", "123");

getAttribute()

getAttribute() 方法用于获取元素的属性:

javascript
const element = document.getElementById("myElement");

// 获取属性
console.log(element.getAttribute("class"));
console.log(element.getAttribute("id"));
console.log(element.getAttribute("data-value"));

removeAttribute()

removeAttribute() 方法用于移除元素的属性:

javascript
const element = document.getElementById("myElement");

// 移除属性
element.removeAttribute("disabled");
element.removeAttribute("data-value");

直接访问属性

对于某些标准属性,可以直接通过元素对象访问:

javascript
const element = document.getElementById("myElement");

// 直接访问属性
element.id = "newId";
element.className = "newClass";
element.src = "image.jpg";
element.href = "https://example.com";
element.disabled = true;

2. 修改内容

textContent

textContent 属性用于获取或设置元素的文本内容:

javascript
const element = document.getElementById("myElement");

// 获取文本内容
console.log(element.textContent);

// 设置文本内容
element.textContent = "新的文本内容";

innerHTML

innerHTML 属性用于获取或设置元素的 HTML 内容:

javascript
const element = document.getElementById("myElement");

// 获取 HTML 内容
console.log(element.innerHTML);

// 设置 HTML 内容
element.innerHTML = "<strong>加粗文本</strong>";

注意:使用 innerHTML 可能会导致安全问题(如 XSS 攻击),并且性能较差,应尽量避免使用。

innerText

innerText 属性用于获取或设置元素的可见文本内容:

javascript
const element = document.getElementById("myElement");

// 获取可见文本内容
console.log(element.innerText);

// 设置可见文本内容
element.innerText = "新的可见文本内容";

注意innerText 考虑了样式,会忽略不可见的文本,而 textContent 会获取所有文本内容,包括不可见的。

3. 修改样式

style 属性

使用 style 属性修改元素的内联样式:

javascript
const element = document.getElementById("myElement");

// 修改样式
element.style.color = "red";
element.style.fontSize = "20px";
element.style.backgroundColor = "yellow";
element.style.padding = "10px";
element.style.margin = "5px";
element.style.border = "1px solid black";

classList

使用 classList 属性管理元素的类:

javascript
const element = document.getElementById("myElement");

// 添加类
element.classList.add("class1", "class2");

// 移除类
element.classList.remove("class1", "class2");

// 切换类
element.classList.toggle("active");

// 检查类是否存在
console.log(element.classList.contains("active"));

// 替换类
element.classList.replace("oldClass", "newClass");

遍历 DOM 元素

1. 遍历子元素

javascript
const parent = document.getElementById("parent");

// 使用 children 属性
const children = parent.children;
for (let i = 0; i < children.length; i++) {
  console.log(children[i]);
}

// 使用 firstElementChild 和 nextElementSibling
let current = parent.firstElementChild;
while (current) {
  console.log(current);
  current = current.nextElementSibling;
}

2. 遍历所有后代元素

javascript
function traverse(element) {
  console.log(element);
  const children = element.children;
  for (let i = 0; i < children.length; i++) {
    traverse(children[i]);
  }
}

const root = document.getElementById("root");
traverse(root);

最佳实践

1. 缓存 DOM 引用

避免重复获取相同的 DOM 元素:

javascript
// 好的做法:缓存 DOM 引用
const element = document.getElementById("myElement");
for (let i = 0; i < 10; i++) {
  element.textContent = i;
}

// 不好的做法:重复获取 DOM 元素
for (let i = 0; i < 10; i++) {
  document.getElementById("myElement").textContent = i;
}

2. 使用文档片段

使用文档片段减少 DOM 操作次数:

javascript
// 好的做法:使用文档片段
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
  const div = document.createElement("div");
  div.textContent = i;
  fragment.appendChild(div);
}
document.getElementById("container").appendChild(fragment);

// 不好的做法:多次操作 DOM
const container = document.getElementById("container");
for (let i = 0; i < 1000; i++) {
  const div = document.createElement("div");
  div.textContent = i;
  container.appendChild(div);
}

3. 使用现代选择器

优先使用 querySelector()querySelectorAll()

javascript
// 好的做法:使用 querySelector
const element = document.querySelector("#container .item");

// 不好的做法:使用 getElementById 和 getElementsByClassName
const container = document.getElementById("container");
const items = container.getElementsByClassName("item");
const element = items[0];

4. 避免使用 innerHTML

尽量使用 DOM 方法替代 innerHTML

javascript
// 好的做法:使用 DOM 方法
const div = document.createElement("div");
const text = document.createTextNode("Hello");
div.appendChild(text);
document.getElementById("container").appendChild(div);

// 不好的做法:使用 innerHTML
document.getElementById("container").innerHTML = "<div>Hello</div>";

5. 使用事件委托

对于多个相似元素的事件,使用事件委托:

javascript
// 好的做法:使用事件委托
const container = document.getElementById("container");
container.addEventListener("click", function (event) {
  if (event.target.classList.contains("item")) {
    console.log("Item clicked:", event.target.textContent);
  }
});

// 不好的做法:为每个元素添加事件监听器
const items = document.querySelectorAll(".item");
items.forEach((item) => {
  item.addEventListener("click", function () {
    console.log("Item clicked:", this.textContent);
  });
});

小结

DOM 元素是 HTML 文档在 DOM 树中的表示,通过 DOM API 我们可以访问、创建、修改和删除元素。本文介绍了如何使用各种方法来操作 DOM 元素,包括访问元素、创建和插入元素、删除和替换元素、修改元素的属性和内容等。在实际开发中,应该遵循最佳实践,提高代码的性能和可维护性。