这是我在问题jquery input select all on focus中提出的解决方案:
$("input").focus(function(){
$(this).on("click.a keyup.a", function(e){
$(this).off("click.a keyup.a").select();
});
});
$("input").focus(function(){
$(this).on("mouseup.a keyup.a", function(e){
$(this).off("mouseup.a keyup.a").select();
});
});
// event logger
$("input").on("mousedown focus mouseup click blur " +
"keydown keypress keyup change",
function(e) {
console.log(e.type);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value="potato" />
<input type="text" value="tomato" />
问题:
这里稍微解释一下:
首先,让我们看一下鼠标或 Tab 进入字段时的事件顺序。
我们可以像这样记录所有相关事件:
$("input").on("mousedown focus mouseup click blur keydown keypress keyup change",
function(e) { console.log(e.type); });
某些浏览器会在mouseup 事件期间尝试定位光标。这是有道理的,因为您可能希望在一个位置开始插入符号并拖动以突出显示某些文本。在您实际抬起鼠标之前,它无法指定插入符号的位置。因此,处理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。相反,只要按下 click 或 keyup,我们就会调用我们的函数。我们要做的第一件事是删除两者的处理程序。这样一来,我们是用标签还是鼠标输入都无关紧要。该函数应该只执行一次。
注意:大多数浏览器在tab事件期间自然会选择所有文本,但是作为animatedgif pointed out,我们还是要处理keyup事件,否则click事件仍然会一直徘徊大约在我们加入选项卡的任何时间。我们会同时收听这两种情况,因此我们可以在处理完选择后立即关闭监听器。
现在,我们可以在浏览器做出选择后调用select(),所以我们一定会覆盖默认行为。
最后,为了获得额外的保护,我们可以将event namespaces 添加到click 和keyup 函数中,这样.off() 方法就不会删除任何其他可能正在运行的侦听器。
另外,如果你想用function called once that will fire exactly once for any number of events扩展jQuery:
//The handler is executed at most once per element for all event types.
$.fn.once = function (events, callback) {
return this.each(function () {
$(this).on(events, myCallback);
function myCallback(e) {
$(this).off(events, myCallback);
callback.call(this, e);
}
});
};
然后你可以像这样进一步简化代码:
$("input").focus(function(){
$(this).once("click keyup", function(e){
$(this).select();
});
});
//The handler is executed at most once per element for all event types.
$.fn.once = function (events, callback) {
return this.each(function () {
$(this).on(events, myCallback);
function myCallback(e) {
$(this).off(events, myCallback);
callback.call(this, e);
}
});
};
$("input").focus(function(){
$(this).once("click keyup", function(e){
$(this).select();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value="potato" />
<input type="text" value="tomato" />
在 IE 10+、FF 28+ 和 Chrome 35+ 中测试