javascript 寻找更好的解决方法来解决 Chrome 选择焦点错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3380458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 01:01:41  来源:igfitidea点击:

Looking for a better workaround to Chrome select on focus bug

javascriptjquerywebkit

提问by Jenni

I have the same problem as the user in this question, which is due to this bugin Webkit. However, the workaround provided will not work for my app. Let me re-state the problem so that you don't have to go read another question:

我有同样的问题在用户这一问题,这是由于这个bug在WebKit的。但是,提供的解决方法不适用于我的应用程序。让我重新陈述这个问题,这样你就不必去阅读另一个问题:

I am trying to select all the text in a textarea when it gets focus. The following jQuery code works in IE/FF/Opera:

我试图在获得焦点时选择 textarea 中的所有文本。以下 jQuery 代码适用于 IE/FF/Opera:

$('#out').focus(function(){
  $('#out').select();
});

However, in Chrome/Safari the text is selected--very briefly--but then the mouseUp event is fired and the text is deselected. The following workaround is offered in the above links:

然而,在 Chrome/Safari 中,文本被选中——非常简短——但随后 mouseUp 事件被触发并且文本被取消选择。以上链接提供了以下解决方法:

$('#out').mouseup(function(e){
  e.preventDefault();
});

However, this workaround is no good for me. I want to select all text onlywhen the user gives the textarea focus. He mustthen be able to select only part of the text if he chooses. Can anyone think of a workaround that still meets this requirement?

但是,这种解决方法对我没有好处。我想选择所有文字只有当用户给出textarea的焦点。如果他愿意,那么他必须只能选择文本的一部分。谁能想到仍然满足此要求的解决方法?

采纳答案by tcooc

How about this?

这个怎么样?

$('#out').focus(function () {
    $('#out').select().mouseup(function (e) {
        e.preventDefault();
        $(this).unbind("mouseup");
    });
});

回答by Adrian Heine

The accepted answer (and basically every other solution I found so far) does not work with keyboard focus, i. e. pressing tab, at least not in my Chromium 21. I use the following snippet instead:

接受的答案(以及到目前为止我发现的基本上所有其他解决方案)不适用于键盘焦点,即按 Tab 键,至少在我的 Chromium 21 中不是。我使用以下代码片段:

$('#out').focus(function () {
  $(this).select().one('mouseup', function (e) {
    $(this).off('keyup');
    e.preventDefault();
  }).one('keyup', function () {
    $(this).select().off('mouseup');
  });
});

e.preventDefault()in the keyupor focushandler does not help, so the unselecting after a keyboard focus seems to not happen in their default handlers, but rather somewhere between the focusand keyupevents.

e.preventDefault()keyuporfocus处理程序中没有帮助,因此在键盘焦点之后取消选择似乎不会发生在它们的默认处理程序中,而是发生在focuskeyup事件之间。

As suggested by @BarelyFitz, it might be better to work with namespaced events in order to not accidentally unbind other event handlers. Replace 'keyup'with 'keyup.selectText'and 'mouseup'with 'mouseup.selectText'for that.

正如@BarelyFitz 所建议的那样,最好使用命名空间事件,以免意外解除其他事件处理程序的绑定。更换'keyup''keyup.selectText''mouseup''mouseup.selectText'了点。

回答by Barbarab

Why not simply:

为什么不简单:

$('#out').focus(function(){
    $(this).one('mouseup', function() {
        $(this).select();
    });
});

Seems to work in all major browsers...

似乎适用于所有主要浏览器......

回答by tpankake

A very slightly different approach would be to separate the focus event from the mouse sequence. This works really nicely for me - no state variables, no leaked handlers, no inadvertent removal of handlers, and it works with click, tab, or programmatic focus. Code and jsFiddle below -

一种稍微不同的方法是将焦点事件与鼠标序列分开。这对我来说非常有效 - 没有状态变量,没有泄漏的处理程序,没有无意中删除处理程序,并且它适用于单击、选项卡或程序化焦点。下面的代码和 jsFiddle -

$('#out').focus(function() {
    $(this).select();
});
$('#out').on('mousedown.selectOnFocus', function() {
    if (!($(this).is(':focus'))) {
        $(this).focus();
        $(this).one('mouseup.selectOnFocus', function(up) {
            up.preventDefault();
        });
    }
});

https://jsfiddle.net/tpankake/eob9eb26/27/

https://jsfiddle.net/tpankake/eob9eb26/27/

回答by finpup

Select the text before putting the focus on the input box.

在将焦点放在输入框之前选择文本。

$('#out').select().focus();

回答by zneak

Make a bool. Set it to trueafter a focus event and reset it after a mouse up event. During the mouse up, if it's true, you know the user just selected the text field; therefore you know you must prevent the mouse up from happening. Otherwise, you must let it pass.

制作一个bool. 将其设置为true在焦点事件之后并在鼠标向上事件之后重置。在鼠标向上时,如果是true,您就知道用户刚刚选择了文本字段;因此,您知道必须防止鼠标向上移动。否则,你必须让它过去。

var textFieldGotFocus = false;

$('#out').focus(function()
{
    $('#out').select();
    textFieldGotFocus = true;
});

$('#out').mouseup(function(e)
{
    if (textFieldGotFocus)
        e.preventDefault();
});

$(document).mouseup(function() { textFieldGotFocus = false; });

It's important that you put the mouseup listener that resets the variable on document, since it's not guaranteed that the user will release the mouse button over the text field.

将重置变量的 mouseup 侦听器放在 上很重要document,因为不能保证用户会在文本字段上释放鼠标按钮。

回答by Terje

onclick="var self = this;setTimeout(function() {self.select();}, 0);"

回答by Jai

digitalfresh's solution is mostly there, but has a bug in that if you manually trigger .focus() using JS (so not using a click), or if you tab to the field, then you get an unwanted mouseup event bound - this causes the first click that should deselect the text to be ignored.

digitalfresh 的解决方案主要在那里,但有一个错误,如果您使用 JS 手动触发 .focus()(因此不使用单击),或者如果您使用 Tab 键到该字段,那么您会收到一个不需要的 mouseup 事件绑定 - 这会导致首先单击应取消选择要忽略的文本。

To solve:

要解决:

var out = $('#out');
var mouseCurrentlyDown = false;

out.focus(function () {
  out.select();

  if (mouseCurrentlyDown) {
    out.one('mouseup', function (e) {
      e.preventDefault();
    });  
  }
}).mousedown(function() {
  mouseCurrentlyDown = true;
});

$('body').mouseup(function() {
  mouseCurrentlyDown = false;
});

Note: The mouseup event should be on body and not the input as we want to account for the user mousedown-ing within the input, moving the mouse out of the input, and then mouseup-ing.

注意:mouseup 事件应该在 body 上而不是在输入上,因为我们要考虑用户在输入中按下鼠标,将鼠标移出输入,然后按下鼠标。

回答by Drew

tpankake's answer converted to a reusable jQuery function..
(If you upvote this, please also upvote his answer)

tpankake 的答案已转换为可重用的 jQuery 函数..
(如果您对此表示支持,也请支持他的回答)

Load the following AFTER loading the jQuery library:

加载 jQuery 库后加载以下内容:

$.fn.focusSelect = function () {
    return this.each(function () {
        var me = $(this);
        me.focus(function () {
            $(this).select();
        });
        me.on('mousedown.selectOnFocus', function () {
            var me2 = $(this);
            if (me2.is(':focus') === false) {
                me2.focus();
                me2.one('mouseup.selectOnFocus', function (up) {
                    up.preventDefault();
                });
            }
        });
    });
};

Use it like this:

像这样使用它:

$(document).ready(function () {
    // apply to all inputs on the page:
    $('input[type=text]').focusSelect();

    // apply only to one input
    $('#out').focusSelect();
});