【问题标题】:Google Chrome: Focus issue with the scrollbarGoogle Chrome:滚动条的焦点问题
【发布时间】:2010-11-23 15:32:00
【问题描述】:

我正在使用 jQuery 1.3.2。

表单中有一个输入字段。 单击输入字段会打开一个 div 作为下拉列表。 div 包含项目列表。由于列表很大,因此 div 中有一个垂直滚动条。

要在外部单击时关闭下拉菜单,输入字段上有一个模糊事件。

现在的问题是:

在 chrome(2.0.172) 中,当我们点击滚动条时,输入框会失去焦点。 现在如果你在外面点击,那么下拉菜单不会关闭(因为当你点击滚动条时输入已经失去焦点)

在Firefox(3.5)、IE(8)、opera(9.64)、safari()中,当我们点击滚动条时,输入框不会失去焦点。因此,当您单击外部时(单击滚动条后),下拉菜单将关闭。这是预期的行为。

因此,一旦单击滚动条,在 chrome 中,如果我在下拉列表之外单击,则不会关闭。 我怎样才能用 chrome 解决这个问题。

【问题讨论】:

    标签: javascript jquery cross-browser google-chrome scrollbar


    【解决方案1】:

    好吧,我在下拉控件中遇到了同样的问题。我已经就这个问题向 Chrome 开发人员询问过,他们说 a bug 不会在最近的将来修复,因为“很多人都没有报告过这个问题,而且修复也不是微不足道的”。所以,让我们面对现实:这个 bug 至少还会存在一年。

    不过,对于这种特殊情况(下拉菜单),有一种解决方法。诀窍是:当单击滚动条时,“鼠标按下”事件会到达该滚动条的所有者元素。我们可以使用这个事实来设置一个标志并在“onblur”处理程序中检查它。解释如下:

    <input id="search_ctrl">
    <div id="dropdown_wrap" style="overflow:auto;max-height:30px">
      <div id="dropdown_rows">
        <span>row 1</span>
        <span>row 2</span>
        <span>row 2</span>
      </div>
    </div>
    

    "dropdown_wrap" div 将获得一个垂直滚动条,因为它的内容不适合固定高度。一旦我们得到点击,我们就很确定滚动条被点击并且焦点将被取消。现在一些代码如何处理这个:

    search_ctrl.onfocus = function() {
      search_has_focus = true
    }
    
    search_ctrl.onblur = function() {
      search_has_focus = false
      if (!keep_focus) {
        // hide dropdown
      } else {
        keep_focus = false;
        search_ctrl.focus();
      }
    }
    
    dropdow_wrap.onclick = function() {
      if (isChrome()) {
        keep_focus = search_has_focus;
      }
    }
    

    就是这样。我们不需要对 FF 进行任何黑客攻击,因此可以检查浏览器。在 Chrome 中,我们检测滚动条的点击,允许在不关闭列表的情况下模糊焦点,然后立即将焦点恢复回输入控件。当然,如果我们对“search_ctrl.onfocus”有一些逻辑,它也应该被修改。请注意,我们需要检查 search_ctrl 是否有焦点,以防止双击出现问题。

    您可能会猜想,取消 onblur 事件可能更好,但这在 Chrome 中不起作用。不确定这是错误还是功能。

    附: “dropdown_wrap”不应有任何填充或边框,否则用户可以点击该区域,我们会将其视为滚动条点击。

    【讨论】:

    【解决方案2】:

    我无法得到这些答案,可能是因为它们是从 2009 年开始的。我刚刚处理了这个问题,我认为 ihsoft 走在正确的轨道上,但有点笨拙。

    有两个功能

    onMouseDown() {
        lastClickWasDropdown=true;
    }
    onBlur() {
        if (lastClickWasDropdown) {
            lastClickWasDropdown = false;
            box.focus();
        } else {
            box.close();
        }
    }
    

    诀窍在于如何绑定元素。 onMouseDown 事件应该在“容器” div 上,该 div 包含将被单击的所有内容(即文本框、下拉箭头、下拉框及其滚动条)。 Blur 事件(或 jQuery 中的 focusout 事件)应直接绑定到文本框。

    经过测试并且有效!

    【讨论】:

      【解决方案3】:

      我遇到了同样的情况/问题,我测试了“ihsoft”的解决方案,但它有一些问题。所以我为此研究了一个替代方案,只制作了一个类似于“ihsoft”但有效的一个。这是我的解决方案:

      var hide_dropdownlist=true;
      
      search_ctrl.onblur = function() {
      
        search_has_focus = false
        if (hide_dropdownlist) {
          // hide dropdown
        } else {
          hide_dropdownlist = true;
          search_ctrl.focus();
        }
      }
      
      dropdow_wrap.onmouseover = function() {
          hide_dropdownlist=false;
      }
      dropdow_wrap.onmouseoout = function() {
          hide_dropdownlist=true;
      }
      

      我希望这会对某人有所帮助。

      【讨论】:

        【解决方案4】:

        早些时候我也遇到过这种情况,这就是我一直在做的事情。

        $('html').click(function() {
            hasFocus = 0;
            hideResults();
        });
        

        在输入字段上我会这样做

        $('input').click()
        {
            event.stopPropagation();
        
        }
        

        因此,如果单击 div 之外的任何位置(甚至是滚动条),这将关闭下拉菜单。 但我想如果有人可以提供更合乎逻辑的解决方案。

        【讨论】:

        • 我做了同样的事情,但将其应用于focusout 事件。
        【解决方案5】:

        您能否将模糊事件也设置为在下拉 div 上触发?这样,当输入 下拉框失去焦点时,它就会消失...

        【讨论】:

        • 感谢您的回复。但是如果我在下拉 div 上添加一个模糊事件,那么当单击输入字段时下拉将关闭。我不想要的。
        • 然后检查输入字段和下拉列表是否都没有焦点。如果它们都模糊不清,则删除该列表。
        • 单击下拉列表中的滚动条时,不会触发附加到下拉 div 的单击事件。我猜滚动条不被认为是 DIV 的一部分。
        • 我不认为你可以将 blur 事件添加到 a div。 jsfiddle.net/aamir/GQxeQ/1
        【解决方案6】:

        我很好奇...
        您使用的是每个浏览器的最新版本,为什么不在 chrome 4.0.202 中尝试一下?

        【讨论】:

        • Chrome 2 是最新的稳定版
        【解决方案7】:

        不是检测模糊,而是检测 document.body 或窗口单击并抓住鼠标点。确定此鼠标点是否在菜单框之外。 presto,您已经检测到他们何时在框外点击!

        【讨论】:

          【解决方案8】:

          我通过以下方式解决了这个问题:

          #my_container 是具有“溢出:自动”CSS 规则的容器

          $('#my_container')  
              .mouseenter(function(){  
              //  alert('ctr in!');  
              mouse_in_container = true;  
              })  
          
              .mouseleave(function(){   
               //  alert('ctr out!');  
               mouse_in_container = false;  
              });  
          

          然后:

          $('input').blur(function(){
            if(mouse_in_container)
              return;
            ... Normal code for blur event ...
          });
          

          当我在下拉列表中选择一个元素时,我将代码重写为:

                  (>> ADDED THIS) mouse_in_container=false;
                  $('input').attr('active', false); // to blur input
                  $('#my_container').hide();
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-01-15
            • 1970-01-01
            • 1970-01-01
            • 2016-10-30
            相关资源
            最近更新 更多