[英]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
这是表格的屏幕截图:
如果先将文本框聚焦,然后单击按钮,则可以在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.target
是label
元素,一次是复选框。
因此,一般的解决方法是:
event.preventDefault()
标签和复选框的同时mousedown
event.preventDefault()
。 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.