经过仔细审查,我建议在此线程中将此作为更清洁的解决方案:
$("input").focus(function(){
$(this).on("click.a keyup.a", function(e){
$(this).off("click.a keyup.a").select();
});
});
问题:
这里稍微解释一下:
首先,让我们看一下鼠标或 Tab 进入字段时的事件顺序。
我们可以像这样记录所有相关事件:
$("input").on("mousedown focus mouseup click blur keydown keypress keyup change",
function(e) { console.log(e.type); });
注意:我已将此解决方案更改为使用 click 而不是 mouseup,因为它发生在事件管道的后期,并且根据 @Jocie 的评论似乎在 Firefox 中引起了一些问题
某些浏览器会在mouseup 或click 事件期间尝试定位光标。这是有道理的,因为您可能希望在一个位置开始插入符号并拖动以突出显示某些文本。在您实际抬起鼠标之前,它无法指定插入符号的位置。因此,处理focus 的函数注定会过早响应,让浏览器覆盖您的定位。
但问题是我们确实想要处理焦点事件。它让我们知道有人第一次进入该领域。在那之后,我们不想继续覆盖用户选择行为。
解决方案:
相反,在focus 事件处理程序中,我们可以快速为即将触发的click(单击)和keyup(制表符)事件附加侦听器。
注意:tab事件的keyup实际上是fire in the new input field, not the previous one
我们只想触发一次事件。我们可以使用.one("click keyup),但这将使用call the event handler once for each event type。相反,只要按下 mouseup 或 keyup,我们就会调用我们的函数。我们要做的第一件事是删除两者的处理程序。这样一来,我们是用标签还是鼠标输入都无关紧要。该函数应该只执行一次。
注意:大多数浏览器在tab事件期间自然会选择所有文本,但是作为animatedgif pointed out,我们还是要处理keyup事件,否则mouseup事件仍然会持续存在大约在我们加入选项卡的任何时间。我们会同时收听这两种情况,因此我们可以在处理完选择后立即关闭监听器。
现在,我们可以在浏览器做出选择后调用select(),所以我们一定会覆盖默认行为。
最后,为了获得额外的保护,我们可以将event namespaces 添加到mouseup 和keyup 函数中,这样.off() 方法就不会删除任何其他可能正在运行的侦听器。
在 IE 10+、FF 28+ 和 Chrome 35+ 中测试
或者,如果您想使用 function called once that will fire exactly once for any number of events 扩展 jQuery:
$.fn.once = function (events, callback) {
return this.each(function () {
var myCallback = function (e) {
callback.call(this, e);
$(this).off(events, myCallback);
};
$(this).on(events, myCallback);
});
};
然后你可以像这样进一步简化代码:
$("input").focus(function(){
$(this).once("click keyup", function(e){
$(this).select();
});
});