这是我在问题
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();
});
});
$("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" />
问题:
这里有一点解释:
首先,让我们看一下当您将鼠标或制表符移到字段中时事件的顺序。
我们可以像这样记录所有相关事件:
$("input").on("mousedown focus mouseup click blur keydown keypress keyup change",
function(e) { console.log(e.type); });
![focus events](https://i.imgur.com/JbU30dD.png)
一些浏览器在
mouseup
事件期间尝试定位光标。这是有道理的,因为您可能想要从一个位置开始拖动以突出显示一些文本。直到您实际抬起鼠标,它才能确定光标位置。因此,处理
focus
的函数注定会太早响应,使浏览器覆盖您的定位。
但问题在于我们确实希望处理焦点事件。它让我们知道第一次有人进入该字段。在那之后,我们不想继续覆盖用户选择行为。
解决方案:
相反,在
focus
事件处理程序内,我们可以快速附加即将触发的
click
(单击)和
keyup
(切换)事件的侦听器。
注意:Tab 事件的 keyup 实际上会在新输入字段中触发,而不是在先前的字段中。
我们只想触发一次事件。我们可以使用
.one("click keyup)
,但这会
对每个事件类型调用事件处理程序一次。相反,只要按下单击或键盘弹起键,我们就会调用函数。首先,我们将删除两者的处理程序。这样,无论我们是通过制表符还是鼠标进入,都不会有影响。该函数应该只执行一次。
注意:大多数浏览器在选项卡事件期间自然选择所有文本,但正如动画GIF所指出的, 我们仍然希望处理keyup
事件,否则click
事件仍会在我们制表符后悬而未决。我们同时监听两个事件,以便我们在处理选择后立即关闭监听器。
现在,我们可以在浏览器进行其选择后调用
select()
,以确保覆盖默认行为。
最后,为了额外保护,我们可以在
click
和
keyup
函数中添加
事件命名空间,这样
.off()
方法就不会删除其他可能在使用的监听器。
此外,如果您想使用一个名为
once
的函数扩展jQuery,以便它可以在任意数量的事件中仅触发一次:
$.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();
});
});
$.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+中测试过。
preventDefault();
吗? - LazaruspreventDefault();
替换return false;
,因为这可以涵盖许多return false;
无法涵盖的错误。 - Lazarusevent.stopPropagation()
不起作用,必须使用return false;
代替。 - Andy E