单击div的滚动条会触发I.E中的模糊事件

时间:2010-01-07 21:24:17

标签: javascript jquery internet-explorer onblur

我有一个div,就像一个下拉菜单。因此,当您单击按钮时弹出窗口,它允许您滚动浏览此大列表。所以div有一个垂直滚动条。如果你点击div的外部,即在模糊时,div应该会消失。

问题是,当用户点击div的滚动条时,IE错误地触发了onblur事件,而Firefox却没有。我猜Firefox仍然将滚动条视为div的一部分,我认为这是正确的。我只是希望IE的行为方式相同。

8 个答案:

答案 0 :(得分:16)

我在自动完成下拉列表中遇到了与滚动条类似的问题。由于下拉列表应该在附加的表单元素失去焦点时隐藏,因此保持对正确元素的关注成为一个问题。单击滚动条时,只有Firefox(10.0)继续关注输入元素。 IE(8.0),Opera(11.61),Chrome(17.0)和Safari(5.1)都从输入中删除了焦点,导致下拉列表被隐藏,并且由于它被隐藏,点击事件不会在下拉列表中触发。

幸运的是,在大多数问题浏览器中,可以轻松避免焦点转移。这是通过取消默认浏览器操作来完成的:

dropdown.onmousedown = function(event) {
    // Do stuff
    return false;
}

向事件处理程序添加返回值,从而排除IE以外的所有浏览器上的问题。这样做会取消默认的浏览器操作,在这种情况下是焦点移动。此外,使用mousedown而不是click意味着事件处理程序将在输入元素上触发blur事件之前执行。

这使得IE成为唯一存在的问题(不出意外)。事实证明,没有办法取消IE的焦点转移。幸运的是,IE是唯一一个在下拉列表中触发焦点事件的浏览器,这意味着可以使用IE独占事件处理程序恢复对输入元素的关注:

dropdown.onfocus = function() {
    input.focus();
}

IE的解决方案并不完美,但是当焦点转移无法取消时,这是您可以做到的最佳选择。会发生的是,模糊事件会在输入上触发,隐藏下拉列表,之后焦点会触发现在隐藏的下拉列表,从而将焦点恢复为输入并触发显示下拉列表。在我的代码中它还触发重新填充下拉列表,导致短暂的延迟和选择的丢失,但如果用户想要滚动选择可能无用,所以我认为这是可接受的。

我希望这很有帮助,即使我的例子与问题略有不同。从我收集到的,问题是关于IE在下拉列表上触发模糊事件,而不是打开它的按钮,这对我没有意义......就像我使用焦点事件处理程序指示,单击滚动条应该将焦点移动到滚动条在IE上的一部分。

答案 1 :(得分:4)

迟到的答案,但我遇到了同样的问题,目前的答案对我没有用。

popup元素的悬停状态按预期工作,因此在您的模糊事件中,您可以检查您的弹出元素是否悬停,只有删除/隐藏它才会显示:

$('#element-with-focus').blur(function()
{
    if ($('#popup:hover').length === 0)
    {
        $('#popup').hide()
    }
}

您需要将焦点移回到已绑定模糊事件的原始元素。这不会干扰滚动:

$('#popup').focus(function(e)
{
    $('#element-with-focus').focus();
});

这不适用于IE7或更低版​​本 - 所以只需删除对它的支持......

示例:http://jsfiddle.net/y7AuF/

答案 2 :(得分:3)

当你点击滚动条时,我遇到类似的问题,IE触发模糊事件。显然它只发生在IE7及以下,而IE8在quirksmode中。

这是我通过Google找到的东西

https://prototype.lighthouseapp.com/projects/8887/tickets/248-results-popup-from-ajaxautocompleter-disappear-when-user-clicks-on-scrollbars-in-ie6ie7

如果你知道在文档上某个地方点击的人而不是当前关注的div,你基本上只会做模糊。可以反向检测滚动条点击,因为当您单击滚动条时,document.onclick 不会触发。

答案 3 :(得分:3)

这是一个老问题,但由于它仍适用于IE11,这就是我所做的。

我在菜单上听mousedown事件并在此事件上设置一个标志。当我捕捉模糊事件时,如果mousedown标志打开,我将焦点设置回来。由于Edge,FF和Chrome不会触发模糊事件,但会触发鼠标事件(IE赢了),我为它们重置鼠标上的mousedown标志(在IE的模糊上)。 / p>

  mousedown: function (e) {
      this.mouseddown = true;
      this.$menu.one("mouseup", function(e){
        // IE won't fire this, but FF and Chrome will so we reset our flag for them here
        this.mouseddown = false;
      }.bind(this));
    }

 blur: function (e) {
      if (!this.mouseddown && this.shown) {
        this.hide();
        this.focused = false;        
      } else if (this.mouseddown) {
        // This is for IE that blurs the input when user clicks on scroll.
        // We set the focus back on the input and prevent the lookup to occur again
        this.skipShowHintOnFocus = true; // Flag used to avoid repopulating the menu
        this.$element.focus();
        this.mouseddown = false;    
      } 
    },

这样菜单保持可见,用户不会丢失任何东西。

答案 4 :(得分:1)

使用focusout和focusin(IE特定事件)

$(document).bind('focusout', function(){
     preventHiding = false;
     //trigger blur event
     this.$element.trigger('blur');

});

$(document).bind('focusin', function(){
     preventHiding = true;
});

$(document).bind('blur', function(){
       // Did anyone want us to prevent hiding?
       if (this.preventHiding) {
         this.preventHiding = false;
         return;
       }
       this.hide();
});

答案 5 :(得分:0)

我有同样的问题。通过将菜单放在包装(更大)div中解决。随着模糊应用于包装器,它工作!

答案 6 :(得分:0)

也许尝试将tabindex属性集-1添加到div节点。

答案 7 :(得分:0)

我认为这不是IE问题。

更多情况是如何设计交互以及在哪里处理哪个事件。 如果相关目标具有唯一的css-class-accessor,则可以通过检查event.relatedTarget的classList中要允许或不允许启动模糊事件的元素来取消模糊事件。从我的ES2015项目中的自定义自动完成下拉列表中查看我的onBlurHandler(您可能需要解决contains()才能获得较早的JS支持):

onBlurHandler(event: FocusEvent) {
  if (event.relatedTarget 
      && (event.relatedTarget as HTMLElement).classList.contains('folding-select-result-list')) {
    // Disallow any blur event from `.folding-select-result-list`
    event.preventDefault();
  } else if (!event.relatedTarget
      || event.relatedTarget 
      && !(event.relatedTarget as HTMLElement).classList.contains('select-item')) {
    // If blur event is from outside (not `.select-item`), clear the suggest list
    // onClickHandler of `.select-item` will clear suggestList as configured with this.clearAfterSelect
    this.clearOptions(this.clearAfterBlur);
  }
}
  • .folding-select-result-list是我的建议下拉菜单,其中有“空点”和“可能是滚动条”,在这里我不需要此模糊事件。
  • .select-item拥有自己的onClickHandler,它触发对选择内容的XHR请求,并在组件this.clearAfterSelect的另一个属性为true时关闭下拉列表。