-1

我是 Javascript 的相对初学者。我来自 Flash OOP 编程(Actionscript 3)的背景,屏幕上的图形对象和Class. 我试图弄清楚是否有可能将这种直接和明确的关系转换为 Javascript/HTML 世界。

例如,如果我有一个在线游戏并且有各种图形区域——一个游戏区、一个输入区、一个记分牌。我希望与这些交互中的每一个都应该由单独的对象或原型(或类或模块)处理。

我的第一个想法是通过事件委托来实现,向覆盖我感兴趣的区域的父图形对象添加一个事件侦听器,并将其链接到代码Object(或Class)中“代表”该图形的“主方法”目的。从那里我可以弄清楚对象的哪一部分被点击并引用了对象内部的方法。这似乎是一条尴尬的下坡路。

或者我可以简单地将事件侦听器添加到图形对象中的各个组件,并将它们链接到代表该图形对象的代码对象内的事件处理程序。我想这可能是正确的答案。

我只是想问是否有任何其他方法可以链接整个图形 DOM 对象和整个代码Objects(或类、原型等),更接近地模仿 Flash 在一个图形对象和一个代码结构之间提供的直接连接?

4

1 回答 1

2

在需要使用 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>

如您所见,事件委托有它的位置,但除非您有事件委托的用例之一,否则将单个对象绑定到事件处理程序通常是常态。

于 2018-06-16T14:25:28.810 回答