标签内的按钮触发器(有时双击触发器)

Button inside label triggers (sometimes double trigger \ double click)

提问人:Sergei Ermakov 提问时间:7/18/2022 更新时间:9/21/2023 访问量:461

问:

有类似的问题,但我没有足够的声誉来发布答案,所以我把它作为“新问题”来做

问题是:

<label>
  <button type="button">something 1</button>
  <button type="button">something 2</button>
  <input>
</label>

如果您要单击标签内的任意位置 - 它将触发第一个按钮,而不是第二个按钮,而不是焦点输入

那是因为它会触发它首先在里面找到的任何东西label

因此,如果您单击按钮 - 您将有 2 次点击:标签将触发第一个按钮,您(作为用户)将触发第二个按钮something 2

它实际上很容易解决

<label for="unique">
  <button type="button">something 1</button>
  <button type="button">something 2</button>
  <input id="unique">
</label>

这样一来,标签将始终知道究竟要触发什么

HTML 按钮 输入 标签

评论

0赞 Andy 7/18/2022
如果您已经找到了问题的答案,请将其作为答案发布,而不是作为问题的一部分。话虽如此,一般建议是“不要在标签内放置锚点或按钮等交互式元素”。
0赞 Andy 7/19/2022
另外,我刚刚看到,每个 HTML 标准都不允许将可标记的元素(包括按钮)放在标签内。
0赞 Sergei Ermakov 7/21/2022
关于你的第一点:不幸的是,我没有足够的声誉(正如我在问题中所说)来发布评论。;;;问题本身被标记为已关闭,因此也无法发布为答案。;;;关于“标准”点 - 不幸的是,标准并不总是有效。例如,它也不应该将“可交互”元素放在彼此内部,但谷歌驱动器做到了(列表项中的按钮,我认为也是按钮)。在我们的案例中,这也是一个相当棘手的情况,我们必须找到解决问题的方法,我想分享它。
0赞 Andy 7/21/2022
没有人会强迫您将这些按钮放在标签元素中,如前所述,这可能是有害的。可以在标签周围创建一个容器,并在该容器上绑定任何事件处理程序。该标准的想法是,您不应该将本机交互元素彼此放在一起。列表项 (G Drive) 本身不是交互式的。关键是可以通过绑定自己的事件处理程序来控制交互性。那么,潜在的问题难道不是如何在父元素和子元素上实现交互性吗?
0赞 Andy 7/21/2022
因此,如果您有兴趣,我们可以尝试找到该问题的解决方案,该解决方案不会让用户感到困惑,并避免在标签中包含多个交互式元素的陷阱。如果是,请将您的最终目标添加到问题中。

答:

2赞 Andy 7/21/2022 #1

一般建议是“不要在标签内放置锚点或按钮等交互式元素。

虽然使用该属性可能会解决单击标签的部分问题,但它会带来其他问题。for

// don’t put buttons in labels!
<label for="unique">
  <button type="button">something 1</button>
  <button type="button">something 2</button>
  <input id="unique">
</label>

HTML 标准不允许在<标签>中添加其他交互式元素

内容模型:
措辞内容,但不包含后代可标记元素,除非它是元素的标记控件,并且没有后代标签元素。

因此,这在今天可能有效,但由于标准不支持它,浏览器供应商可以自由更改行为。

HTML 元素表示用户界面中项的标题。

标签的主要用途是为输入提供可访问的文本,以便用户知道要输入的内容,即使在使用屏幕阅读器或语音控制等辅助技术时也是如此。因此,标签的文本内容将用于标记输入,同时考虑所有包含的文本。它的标题为“something 1 something 2”。

这不是很好,所以我的建议是不要依赖属性来解决点击问题,而是将其分开并自己实现点击行为。for

使用 will 的优点是控件也被分组用于辅助技术,因此将宣布进入或离开具有焦点的组。<fieldset>

focusInput = e => e.currentTarget.querySelector('input').focus();
action = e => {
  alert('Action!');
  e.stopPropagation();
}
<fieldset onclick="focusInput(event)">
  <legend>Group Title</legend>
  <button type="button" onclick="action(event)">something 1</button>
  <button type="button" onclick="action(event)">something 2</button>
  <br>
  <label>
    Input Label
    <input>
  </label>
</fieldset>

请注意,没有键盘处理程序绑定到字段集,因为这会再次使键盘用户感到困惑。