事件处理程序
编辑此页面事件处理程序是指为响应浏览器中发生的特定事件而调用的函数,例如当用户单击某个元素时。
Solid 提供了两种向浏览器添加事件监听器的方法:
- on:__: 向 element 添加事件监听器。这也称为原生事件(native event)。
- on__: 将事件监听器添加到
document
并将其分派到element
。这也被称为委托事件(delegated event)。
使用事件
要添加事件处理程序,在事件名称前加上 on
或 on:
前缀:
委托事件不区分大小写,因此在 Solid 中使用委托事件处理程序可以使用驼峰式或全部小写形式编写。请注意,虽然委托事件可以用两种方式编写,但原生事件区分大小写。
对于其他事件,例如自定义事件或您不希望被代理的事件,使用 on:
属性将原样添加事件处理器,这就是事件处理器区分大小写的原因:
对于使用 on:
的标准或自定义事件的类型,TypeScript 页面有一个关于事件处理器的部分。
绑定事件
要优化事件处理程序,您可以传递一个数组替代原本的函数作为事件处理程序,此时传递到数组的第二个条目将作为处理程序的第一个参数:
在这个例子中 ,点击按钮时,Hello!
字符串将作为 handler
函数中的 data
参数传递。
通过这种方式绑定事件,Solid 避免了使用 JavaScript bind 方法造成的额外闭包开销。
动态处理程序
事件处理程序不是响应式系统的一部分,如果您将处理程序作为信号传递,它将不会响应信号的更改。换句话说,事件不会动态更新,并且绑定也不是响应式。这是因为添加和删除监听器是一项资源密集型任务。
由于事件处理程序的调用方法类似于标准函数,因为你可以将它们设计为在需要时调用响应式资源。
在下面的例子中,handleClick
表示 props 具有调用任何函数的灵活性。因为不需要这些函数是响应式的:
事件委托
Solid 没有将事件监听器添加到每个单独的元素,而是通过 on__ 的形式使用合成事件委托。在这种方法中,事件监听器将添加到 document
元素,并在相关元素冒泡时将事件分派给它们。
通过将事件监听器的数量保持在最低限度,可以更有效地捕获事件。当处理大量元素(例如表格或列表)时特别有用。
click
、input
和 keydown
等受支持的事件只是以这种方式优化的几个示例。要查看完整列表,请参阅下面的委托事件列表。
如果您需要将事件监听器添加到 Solid 的事件委托不支持的元素(例如自定义元素,%20you%20can%20use%20the%20on:__
中的自定义事件),则可以使用 on:__ 形式。
事件委托注意事项
虽然事件委派提供了一些性能增强,但也需要权衡。
事件委托是为通过 JSX 树而不是 DOM 树传播事件而设计的。这可能与之前对事件如何运行和流动的预期不同。
需要记住的一些事情包括:
- 委托事件监听器针对每个事件类型都添加一次,并处理该类型的所有未来事件。这意味着即使添加事件监听器的元素及其处理程序被删除,委托事件监听器仍保持活动状态。例如,如果
div
监听mousemove
并随后被删除,mousemove
事件仍将分派到document
,以防还有另一个元素也在监听鼠标移动。
对于不经常发生的事件,原生事件是更好的解决方案。由于这些事件发生在特定情况下,因此它们不会从通过事件委托获得的性能改进中受益。
event.stopPropagation()
无法按预期工作,因为事件添加到document
而不是element
对于此类情况,建议使用原生事件。例如在接下来的例子中,使用原生事件将阻止事件到达 div native
处理程序,而委托事件则不能。
您可以在 Solid Playground 中查看此示例。
但如果将 button
改为使用原生事件:
- Portals 按照组件树而不是 DOM 树传播事件,这使得它们更易于使用。这意味着当
Portal
添加到body
时,任何事件都会传播到container
。
onChange
和 onInput
事件根据其原生行为工作:
onInput
将在值更改后立即触发- 在
<input>
字段中,onChange
仅在字段失去焦点后触发。
委托事件列表
您可以在我们的源代码中查看此列表(请参阅 DelegatedEvents
)。