action icon indicating copy to clipboard operation
action copied to clipboard

所有元素都可以用 Action 来绑定点击事件吗?

Open cssmagic opened this issue 10 years ago • 1 comments

所有元素都可以用 Action 来绑定点击事件吗?

从技术上来说,Action 对 body 元素内的所有元素生效。但是,我只推荐你对 <a href="..."><button><input type="button"> 等元素使用 Action 来绑定点击事件。

这有几方面的原因,下面一一道来。

语义

上面列出的这些元素都是天生可以与用户进行交互的元素,天生承接用户的点击行为。用户点击它们就是为了触发一些动作,我将它们称为 “动作元素”。

由于这些元素天生具备可交互的特性,浏览器通常也会为它们设置特殊的默认样式,比如暗示可点击的手形鼠标光标、预设的 :hover :focus :active 样式等等。

而除此以外的其它元素大多是以呈现信息为已任,虽然它们也可以被点击、也会产生点击事件,但从语义上看,并不是最佳选择。

移动端

当使用 Action 为 “非动作元素” 绑定动作时,我们会发现在 iOS 浏览器中并不生效。

这是因为 iOS 的浏览器内核对点击事件做了一些 “优化”——如果一个元素不是天生的可交互元素,那么默认情况下:

  • 它将不会响应用户的点击操作。
  • 这个不存在的 “点击事件” 自然也不会向上冒泡。

由此可见,在这类 “非动作元素” 身上使用 Action 存在一定风险。


附:解决方案

当然 iOS 浏览器的这个问题也不是无解的,我们有一些方法可以强制这些 “非动作元素” 响应点击操作:

  • 只要对目标元素或其祖先元素绑定点击事件,浏览器内核就会对该元素另眼相待。(注:为避免副作用,这个用于 hack 的事件监听器可以为空函数;这里的 “祖先元素” 不包括 body 元素和更上层的元素。)

    但显然这个方案不适合 Action。因为找到目标元素绑个事件不仅烦琐,而且 Action 的 “元素不存在也可预先绑定” 的优势也就不存在了。

    (这个方案还有另一个问题:如果这个 hack 是用在目标元素的祖先元素身上的话,则当我们点击该元素时,其祖先元素整体会出现触摸高亮样式,很诡异,需要单独写样式把它去除。)

  • 为目标元素添加一个空的 onclick 属性,也会令浏览器内核对它另眼相待。在 HTML 里直接写或用脚本添加此属性都是可以的。但还是那个问题,需要先对该元素做手脚。

  • 为目标元素添加一个 cursor: pointer 样式,同样可以令浏览器内核意识到该元素需要响应点击操作。这个方法可以做到与 DOM 无关,比较适合 Action。

综上所述,如果你需要对非动作元素使用 Action,就需要对页面应用以下 CSS 规则:

[data-action] {
    cursor: pointer;
}

cssmagic avatar Dec 24 '14 09:12 cssmagic

哈哈哈哈哈

plh97 avatar Apr 19 '18 13:04 plh97