在需要使用 Web UI 的 JavaScript 世界中,文档对象模型 (DOM) API是将 JavaScript 对象连接到构成页面的 HTML 元素的网关。
虽然 DOM 是什么以及可以做什么有很多方面,但它首先要获取对单个 HTML 元素(“节点”引用)或一组 HTML 元素(“节点列表”引用)的 JavaScript 引用。我们不区分这些元素是否“图形化”。我们通常将这些元素中的每一个都视为“节点”。它们是 HTML 文档的一部分,因此它们是我们可以访问的元素“树”的一部分。
获取引用可以通过多种方式完成(id元素的、元素使用的 CSS 类、元素在较大文档结构中的层次位置等)。
这里有些例子:
// Get a DOM node reference via its id
var theDiv = document.getElementById("firstDiv");
console.log(theDiv.textContent);
// Get a DOM node reference based on its position in the document
var theSecondDiv = document.querySelector("#firstDiv + div"); // Sibling following the one with the id
console.log(theSecondDiv.textContent);
// Get a node list of all the elements that have the "special" class
var theSpecials = document.querySelectorAll(".special");
console.log(theSpecials[0].textContent, theSpecials[1].textContent, theSpecials.length);
// Get a node reference based on having a certain attribute value
var theButton = document.querySelector("input[type='button']");
theButton.value = "I have a new value!";
<div id="firstDiv">I'm a div</div>
<div>I'm the second div</div>
<p class="special">I'm a paragraph with a class</p>
<h2 class="special">I'm an h2 with a class</h2>
<input type="button" value="Button">
<input type="text">
获得 DOM 引用后,下一步就是与对象交互,这可能意味着获取/设置属性值、调用方法或配置事件回调函数。
在大多数情况下,HTML 属性将映射到 JavaScript 对象属性。在最后一个示例中,映射到JavaScript DOM 对象引用 ( )的value 属性的属性。除了将原始 HTML 元素的属性转换为属性之外,DOM API 还赋予 DOM 对象引用附加属性。例如,所有节点都有一个,和属性,代表元素的节点将有一个和属性来获取/设置内容为文本或 HTML。其他更独特的 DOM 引用类型将具有更具体的属性。<input type="button">value theButton.value = ...nodeNamenodeTypenodeValue.textContent.innerHTML
DOM API 还为 DOM 对象指定了各种方法。例如,表单元素将有一个.focus()方法来设置 UI 的焦点在该元素上,就好像用户已经选择了该元素或单击了它一样。
现在,对于你的问题...
几乎所有 DOM 元素都支持各种事件,您可以配置单个元素来响应一个或多个事件,或者您可以利用“事件冒泡”并在祖先元素上设置事件处理程序并等待后代中触发的事件冒泡直到祖先。这是您在问题中提到的“事件委托” 。
以下是两者的示例:
// Set an event handler for the <p> element
document.querySelector("p").addEventListener("click", function(){ console.log("You clicked the p"); });
// Event delegation is beneficial in two circumstances.
// 1. When a single function should be used to handle the same event for many different elements
// and you don't want to have to store that callback function with all the different elements
// FYI: all event handlers are automatically passed a reference to the event object that they are handling
document.getElementById("parent").addEventListener("click", function(evt){
console.log("The event was handled at the parent, but it was triggered at: " + evt.target);
});
// 2. When elements will be dynamically added to the document and you can't statically set up event
// handlers for elements that don't exist yet.
let span = document.createElement("span");
span.textContent = "I was dynamically created, but if you click me, I'll immediately work!";
document.getElementById("parent").appendChild(span);
<div id="parent">
<p>Child One (p)<p>
<div>Child Two (div)</div>
</div>
如您所见,事件委托有它的位置,但除非您有事件委托的用例之一,否则将单个对象绑定到事件处理程序通常是常态。