【问题标题】:Looking for a better workaround to Chrome select on focus bug为 Chrome 选择焦点错误寻找更好的解决方法
【发布时间】:2011-03-23 18:25:44
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

  • 一个大 +1 用于发现最常见的问题解决方案中明显的明显缺陷。

标签: javascript jquery webkit


【解决方案1】:

这个怎么样?

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

【讨论】:

  • 可能.one() 是一个更好的方法。
  • +1。我不明白为什么这么多人认为基本的preventDefault() 修复就足够了。它显然有严重的缺陷,但它被建议作为你所看到的任何地方的解决方案。谢谢你解决它。 (虽然是的,我同意@InviS 的观点,.one() 可能是更好的做法)
  • .one() 会更好,但这不能很好地处理选项卡式焦点。
  • 这里是如何使用 jQuery 的 .one() 来做到这一点,正如 @InviS 所建议的那样:$('#out').focus(function () { $('#out').select().one('mouseup', function (e) { e.preventDefault(); }); });
【解决方案2】:

接受的答案(以及到目前为止我发现的所有其他解决方案)不适用于键盘焦点,即。 e.按标签,至少在我的 Chromium 21 中没有。我使用以下 sn-p 代替:

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

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

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

【讨论】:

  • 当您取消绑定事件时,您可能会无意中取消绑定可能在输入上的其他处理程序。为了防止这种情况,您可以使用命名空间,例如“mouseup.selectText”而不是“mouseup”,那么只会删除您的单个事件处理程序。
  • 结合命名空间提示,这是我为这个粘性检票口找到的最佳解决方案,我将它推荐给房子。
【解决方案3】:

为什么不简单:

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

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

【讨论】:

  • 这对我有用。值得注意的是,当您专注于通过代码进行输入时,它似乎不起作用。为了解决这个问题,我使用$('#element').select().focus() 而不是$('#element').focus()
【解决方案4】:

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

【讨论】:

    【解决方案5】:

    创建一个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 上很重要,因为不能保证用户会在文本字段上释放鼠标按钮。

    【讨论】:

    • 谢谢!这激发了一个更简单的想法:而不是 document.mouseup 上的侦听器,只需在 out.mouseup 上将标志设置为 false:if(textFieldGotFocus){ e.preventDefault(); textFieldGotFocus = false;}
    • 天哪。全局变量 + 事件处理 == 解决问题的方法。
    【解决方案6】:
    onclick="var self = this;setTimeout(function() {self.select();}, 0);"
    

    【讨论】:

    • 这个答案启发了:$("#one").on('focus', null, function() { var $that = $(this); setTimeout(function() { $that.select(); }, 0); });
    【解决方案7】:

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

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

    【讨论】:

      【解决方案8】:

      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 上而不是 input 上,因为我们要考虑用户在输入中的 mousedown-ing,将鼠标移出输入,然后 mouseup-ing。

      【讨论】:

        【解决方案9】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-07-20
          • 2019-03-20
          • 1970-01-01
          • 2013-01-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多