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

时间:2010-08-01 02:02:11

标签: javascript jquery webkit

我遇到与this question中的用户相同的问题,这是由于Webkit中的this bug造成的。但是,提供的解决方法不适用于我的应用程序。让我重新陈述问题,这样你就不必去读另一个问题:

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

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

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

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

然而,这种解决方法对我没有好处。我想在用户给出textarea焦点时选择所有文本 only 。如果他选择的话,他必须然后才能选择部分文本。任何人都可以想到仍然符合此要求的解决方法吗?

9 个答案:

答案 0 :(得分:29)

这个怎么样?

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

答案 1 :(得分:25)

接受的答案(基本上我到目前为止找到的所有其他解决方案)都不适用于键盘焦点,i。即按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()keyup处理程序中的

focus没有帮助,因此键盘焦点之后的取消选择似乎不会发生在其默认处理程序中,而是介于{{1}之间}和focus事件。

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

答案 2 :(得分:3)

为什么不简单:

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

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

答案 3 :(得分:2)

制作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; });

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

答案 4 :(得分:2)

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

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

答案 5 :(得分:2)

一种非常不同的方法是将焦点事件与鼠标序列分开。这对我来说非常好用 - 没有状态变量,没有泄漏的处理程序,没有无意中删除处理程序,它适用于点击,制表符或程序化焦点。代码和jsFiddle如下 -

string[] values = {11, 42, 42, 42, 22};
int count = 1;
for(int i = 1; i < values.Count; i++) {
    if(values[i-1] == values[i])
        count++;
    else
        count = 1;
    if(count == 4 && values[i] == "42")
       Execute();  // Change this
    RecordInDb();  // Change this
}

IHTMLButtonElement

答案 6 :(得分:1)

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

答案 7 :(得分:0)

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

要解决:

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;
});

注意:mouseup事件应该在body上,而不是输入,因为我们想要考虑输入中的用户mousedown,将鼠标移出输入,然后进行mouseup-ing。

答案 8 :(得分:0)

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

在加载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();
                });
            }
        });
    });
};

像这样使用它:

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

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