Skip to content

DOM 操作基础

1. 什么是 DOM

DOM(Document Object Model,文档对象模型)是一种编程接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。在网页中,文档通常是 HTML 或 XML 文档。通过 DOM,文档可以被视为一个对象树,其中的每个对象都对应文档中的一个部分。

2. 如何通过 JavaScript 操作 DOM

JavaScript 可以用来操作 DOM,从而动态地更改 HTML 文档的结构、内容和样式。以下是几个常用的 DOM 操作方法:

2.1 选择元素

javascript
// 根据 ID 选择元素
var element = document.getElementById("elementId");

// 根据类名选择元素
var elements = document.getElementsByClassName("className");

// 根据标签名选择元素
var elements = document.getElementsByTagName("tagName");

// 使用 CSS 选择器选择元素,可以是类、ID、数据属性等
var element = document.querySelector(".className");
var elements = document.querySelectorAll(".className");

2.2 修改元素

javascript
// 修改元素的文本内容
element.textContent = "New Text";

// 修改元素的 HTML 内容
element.innerHTML = "<span>New HTML</span>";

// 修改元素的属性
element.setAttribute("attributeName", "attributeValue");

// 修改元素的样式
element.style.color = "red";

2.3 添加和删除元素

javascript
// 创建新元素
var newElement = document.createElement("tagName");

// 添加新元素
element.appendChild(newElement);

// 将新元素插入到现有元素之前
element.insertBefore(newElement, referenceElement);

// 或者使用 insertAdjacentElement
element.insertAdjacentElement("beforebegin", newElement); // 插入到目标元素之前
element.insertAdjacentElement("afterend", newElement); // 插入到目标元素之后

// 删除元素
element.removeChild(newElement);

3. 事件监听

事件监听是 JavaScript 中捕捉用户操作和其他事件的一种方式。事件可以是用户点击、鼠标移动,也可以是文档加载、输入变化等。

添加事件监听器

javascript
element.addEventListener("eventType", function (event) {
  // 使用 event 对象来访问事件的详情
  // 例如阻止默认行为
  event.preventDefault();
  // 事件触发时执行的代码
});

移除事件监听器

javascript
element.removeEventListener("eventType", listenerFunction);

事件监听示例

javascript
var button = document.getElementById("myButton");

button.addEventListener("click", function () {
  alert("Button was clicked!");
});

这个示例中,当用户点击 ID 为 myButton 的按钮时,会弹出一个警告框显示 “Button was clicked!”。

4. 节点遍历

通过节点之间的关系,我们可以在 DOM 树中遍历。

javascript
// 获取元素的父节点
var parent = element.parentNode;

// 获取元素的所有子节点
var children = element.childNodes;

// 获取元素的第一个和最后一个子节点
var firstChild = element.firstChild;
var lastChild = element.lastChild;

// 获取元素的兄弟节点
var nextSibling = element.nextSibling;
var previousSibling = element.previousSibling;

5. DOM 优化

考虑到性能,避免频繁的 DOM 操作是至关重要的,可以通过创建文档片段(Document Fragment)来达到这个目的。

javascript
var fragment = document.createDocumentFragment();

// 直接在fragment上进行各种操作,比如添加子节点等。
fragment.appendChild(someNode);

// 最后再将fragment一次性添加到DOM树中,这样可以减少重绘和重排。
someElement.appendChild(fragment);

总之,DOM 操作和事件监听是 JavaScript 中用于与用户交互和动态修改页面内容的基础工具。通过这些工具,开发者可以创建丰富多彩、交互性强的网页应用。

6. 实际应用案例

案例一:创建一个可交互的 Todo List

  1. HTML 结构
html
<ul id="todoList"></ul>
<input type="text" id="newTask" placeholder="新任务" />
<button id="addTaskButton">添加</button>
  1. JavaScript 实现
javascript
var ulElement = document.getElementById("todoList");
var inputElement = document.getElementById("newTask");
var addButton = document.getElementById("addTaskButton");

addButton.addEventListener("click", function () {
  var newTask = inputElement.value;
  if (newTask) {
    var liElement = document.createElement("li");
    liElement.textContent = newTask;
    ulElement.appendChild(liElement);
    inputElement.value = "";
  }
});

案例二:动态改变文本颜色

  1. HTML 结构
html
<p id="text">这是一段文本。</p>
<button id="changeColorButton">改变颜色</button>
  1. JavaScript 实现
javascript
var textElement = document.getElementById("text");
var buttonElement = document.getElementById("changeColorButton");

buttonElement.addEventListener("click", function () {
  textElement.style.color = textElement.style.color === "red" ? "blue" : "red";
});

案例三:展开/收缩内容

  1. HTML 结构
html
<div id="box">
  <p>这是一段可展开和收缩的文本。</p>
</div>
<button id="toggleButton">展开/收缩</button>
  1. JavaScript 实现
javascript
var boxElement = document.getElementById("box");
var toggleButton = document.getElementById("toggleButton");

toggleButton.addEventListener("click", function () {
  if (boxElement.style.display === "none") {
    boxElement.style.display = "block";
  } else {
    boxElement.style.display = "none";
  }
});

案例四:制作一个图片轮播器

  1. HTML 结构
html
<div id="slider">
  <img src="image1.jpg" class="slide" />
  <img src="image2.jpg" class="slide" />
  <img src="image3.jpg" class="slide" />
</div>
<button id="prevSlide">上一张</button>
<button id="nextSlide">下一张</button>
  1. JavaScript 实现
javascript
var slider = document.getElementById("slider");
var slides = slider.getElementsByClassName("slide");
var currentIndex = 0;

function showSlide(index) {
  for (var i = 0; i < slides.length; i++) {
    slides[i].style.display = i === index ? "block" : "none";
  }
}

document.getElementById("prevSlide").addEventListener("click", function () {
  currentIndex = currentIndex === 0 ? slides.length - 1 : currentIndex - 1;
  showSlide(currentIndex);
});

document.getElementById("nextSlide").addEventListener("click", function () {
  currentIndex = currentIndex === slides.length - 1 ? 0 : currentIndex + 1;
  showSlide(currentIndex);
});

showSlide(currentIndex);

案例五:制作一个模态对话框

  1. HTML 结构
html
<div id="myModal" class="modal">
  <div class="modal-content">
    <span class="close">&times;</span>
    <p>这是一个模态对话框。</p>
  </div>
</div>
<button id="myBtn">打开模态对话框</button>
  1. JavaScript 实现
javascript
var modal = document.getElementById("myModal");
var btn = document.getElementById("myBtn");
var span = document.getElementsByClassName("close")[0];

btn.onclick = function () {
  modal.style.display = "block";
};

span.onclick = function () {
  modal.style.display = "none";
};

window.onclick = function (event) {
  if (event.target === modal) {
    modal.style.display = "none";
  }
};

案例六:制作一个标签页

  1. HTML 结构
html
<div class="tabs">
  <button class="tablinks" onclick="openCity(event, 'London')">伦敦</button>
  <button class="tablinks" onclick="openCity(event, 'Paris')">巴黎</button>
  <button class="tablinks" onclick="openCity(event, 'Tokyo')">东京</button>
</div>

<div id="London" class="tabcontent">
  <h3>伦敦</h3>
  <p>伦敦是英国的首都。</p>
</div>

<div id="Paris" class="tabcontent">
  <h3>巴黎</h3>
  <p>巴黎是法国的首都。</p>
</div>

<div id="Tokyo" class="tabcontent">
  <h3>东京</h3>
  <p>东京是日本的首都。</p>
</div>
  1. JavaScript 实现
javascript
function openCity(evt, cityName) {
  var i, tabcontent, tablinks;
  tabcontent = document.getElementsByClassName("tabcontent");
  for (i = 0; i < tabcontent.length; i++) {
    tabcontent[i].style.display = "none";
  }
  tablinks = document.getElementsByClassName("tablinks");
  for (i = 0; i < tablinks.length; i++) {
    tablinks[i].className = tablinks[i].className.replace(" active", "");
  }
  document.getElementById(cityName).style.display = "block";
  evt.currentTarget.className += " active";
}

案例七:制作一个动态计算器

  1. HTML 结构
html
<input type="text" id="num1" />
<select id="operator">
  <option value="add">+</option>
  <option value="sub">-</option>
  <option value="mul">*</option>
  <option value="div">/</option>
</select>
<input type="text" id="num2" />
<button id="calculate">计算</button>
<p id="result">结果:</p>
  1. JavaScript 实现
javascript
document.getElementById("calculate").addEventListener("click", function () {
  var num1 = parseFloat(document.getElementById("num1").value);
  var num2 = parseFloat(document.getElementById("num2").value);
  var operator = document.getElementById("operator").value;
  var result;
  switch (operator) {
    case "add":
      result = num1 + num2;
      break;
    case "sub":
      result = num1 - num2;
      break;
    case "mul":
      result = num1 * num2;
      break;
    case "div":
      if (num2 === 0) {
        alert("除数不能为0");
        return;
      }
      result = num1 / num2;
      break;
    default:
      alert("未知操作");
      return;
  }
  document.getElementById("result").textContent = "结果:" + result;
});

案例八:制作一个动态生成表格的程序

  1. HTML 结构
html
<input type="number" id="rows" placeholder="行数" />
<input type="number" id="cols" placeholder="列数" />
<button id="generateTable">生成表格</button>
<div id="tableContainer"></div>
  1. JavaScript 实现
javascript
document.getElementById("generateTable").addEventListener("click", function () {
  var rows = document.getElementById("rows").value;
  var cols = document.getElementById("cols").value;
  var tableContainer = document.getElementById("tableContainer");

  var table = document.createElement("table");
  for (var i = 0; i < rows; i++) {
    var tr = document.createElement("tr");
    for (var j = 0; j < cols; j++) {
      var td = document.createElement("td");
      td.textContent = i * cols + j + 1;
      tr.appendChild(td);
    }
    table.appendChild(tr);
  }
  tableContainer.innerHTML = "";
  tableContainer.appendChild(table);
});