Mac OS X 上的默认行为是单击复选框和按钮不会从其他具有焦点的控件(例如,文本框)窃取焦点。我想在网络上实现这个。
我可以让它适用于按钮和复选框本身,但不适用于复选框标签。
以这个jsbin为例:http ://jsbin.com/kopateluze/1/edit?html,console,output
这是表格的屏幕截图:
如果先聚焦文本框,然后单击按钮,则可以使用event.preventDefault()onmousedown防止文本框失去焦点。这很好用。如果您首先关注文本框,然后单击复选框,则同样有效。
但是如果你先聚焦文本框,然后点击复选框的label文本,就不行了;文本框失去焦点。
有没有办法防止单击复选框label从其他控件窃取焦点?
请使用纯 JavaScript,但请随时链接到库中实现的解决方案的源代码。
Chr*_*alo 11
好吧,这就是我能够弄清楚的事情,两年多一点之后。
首先,让我们谈谈激发这个问题的例子。当文本字段具有焦点时,我想防止单击按钮窃取焦点。我仍然希望调用任何按钮单击处理程序,我只是不想移动焦点。
要做到这一点,我们只需要知道按钮接收焦点mousedown,所以防止它就像使用一样简单event.preventDefault():
<input placeholder="First focus me" type="text" />
<br/>
<button
onmousedown="event.preventDefault()"
onclick="console.log('button:click')">
Then click me
</button>Run Code Online (Sandbox Code Playgroud)
请注意,单击按钮会触发单击处理程序,但不会使按钮获得焦点。另请注意,按钮仍然可以通过按下 获得焦点Tab,因此这不会损害键盘访问。
事实证明,只要您使用没有标签的裸复选框,同样的技术就可以完美运行。
<input placeholder="First focus me" type="text" />
<br/>
<input
type="checkbox"
onmousedown="event.preventDefault()"
onclick="console.log('checkbox:click')"
/>
? Then click the checkboxRun Code Online (Sandbox Code Playgroud)
但这确实存在可访问性问题,因为描述复选框的文本与其无关,并且复选框单击目标只是复选框本身,而不是随附的文本。这里的解决方案是添加一个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>Run Code Online (Sandbox Code Playgroud)
如果您单击复选框,这将成功防止复选框窃取焦点。但是,如果您单击复选框旁边的文本,则会从文本框中窃取焦点。
关键在于了解label元素如何与其关联的input元素相互作用。该label元素的click处理实际上被调用两次:一次是在那里event.target是label元素,一旦它在哪里的复选框。
因此,一般的解决方法是:
event.preventDefault()上mousedown的标签和复选框的都有。.click()关联的控件(复选框元素),但仅当event.target等于该label元素时。<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>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3080 次 |
| 最近记录: |