繁体   English   中英

如何防止单击复选框标签窃取焦点

[英]How to prevent clicking on a checkbox's label from stealing focus

Mac OS X上的默认行为是单击复选框和按钮不会从其他具有焦点的控件(例如,文本框)中夺取焦点。 我想在网络上实现。

我可以使它适用于按钮和复选框本身,但不适用于复选框标签。

以这个jsbin为例:
http://jsbin.com/kopateluze/1/edit?html,console,output

这是表格的屏幕截图:

http://jsbin.com/kopateluze/1/edit?html,控制台,输出的屏幕截图

如果先将文本框聚焦,然后单击按钮,则可以在mousedown使用event.preventDefault()来防止文本框失去焦点。 那很好。 而且,如果您首先将焦点放在文本框上,然后单击复选框,则同样的方法也可以。

但是,如果您首先关注文本框,然后单击复选框的label文本,则该文本将无效; 文本框失去焦点。

有没有一种方法可以防止单击复选框label而使其他控件失去焦点?

请使用纯JavaScript,但可以随意链接到库中实现的解决方案的源代码。

好吧,这是事实发生两年多以后我能弄清的。

防止按钮窃取焦点

首先,让我们谈谈激发这个问题的例子。 当文本字段具有焦点时,我想防止单击按钮窃取焦点。 我仍然希望调用任何按钮单击处理程序,只是不想移动焦点。

为此,我们只需要知道按钮会集中在mousedown ,因此防止这种情况就像使用event.preventDefault()一样简单:

 <input placeholder="First focus me" type="text" /> <br/> <button onmousedown="event.preventDefault()" onclick="console.log('button:click')"> Then click me </button> 

请注意,单击按钮会触发单击处理程序,但绝不会导致按钮获得焦点。 还要注意,按钮仍然可以通过按Tab来获得焦点,因此这不会损害键盘访问。

防止复选框窃取焦点

事实证明,只要您使用没有标签的裸露复选框,该技术就可以完美地工作。

 <input placeholder="First focus me" type="text" /> <br/> <input type="checkbox" onmousedown="event.preventDefault()" onclick="console.log('checkbox:click')" /> ⇐ Then click the checkbox 

但这确实存在可访问性问题,因为描述该复选框的文本没有与之相关联,并且该复选框的单击目标只是该复选框本身,而不是随之而来的文本。 解决方案是添加一个label元素,但这是问题开始的地方。

复选框带有标签时的问题

 <input placeholder="First focus me" type="text"> <br/> <label> <input type="checkbox" onmousedown="event.preventDefault()" onclick="console.log('checkbox:click')" /> Then click me </label> 

如果您单击复选框,则可以成功阻止该复选框窃取焦点。 但是,如果单击复选框旁边的文本,则焦点将从文本框中被窃取。

复选框带有标签时的修复

关键在于了解label元素如何与其关联的input元素交互。 label元素的click处理程序实际上被调用两次:一次是event.targetlabel元素,一次是复选框。

因此,一般的解决方法是:

  1. event.preventDefault()标签和复选框的同时mousedown event.preventDefault()
  2. 在两次执行的标签单击处理程序中,但仅在event.target等于label元素时,在关联的控件(复选框元素)上调用.click()

 <input placeholder="First focus me" type="text" /> <br/> <label for="checkbox" onmousedown="event.preventDefault()" onclick=" console.log('label:click'); if (this === event.target) { console.log('label === event.target'); console.log('label:click preventDefault()'); // prevent focus and click event.preventDefault(); // call click on the labeled control this.control && this.control.click(); } "> <input id="checkbox" type="checkbox" onmousedown="event.preventDefault()" onclick=" console.log('checkbox:click', `checked = ${this.checked}`); " /> Then click me </label> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM