Javascript 单击div';s滚动条触发模糊事件,即

Javascript 单击div';s滚动条触发模糊事件,即,javascript,jquery,internet-explorer,onblur,Javascript,Jquery,Internet Explorer,Onblur,我有一个像下拉菜单一样的div。因此,当你点击一个按钮时,它会弹出,允许你滚动浏览这个大列表。因此div有一个垂直滚动条。如果在div外单击,即单击“模糊”,则div应消失 问题在于,当用户点击div的滚动条时,IE错误地触发了onblur事件,而Firefox没有。我猜Firefox仍然将滚动条视为div的一部分,我认为这是正确的。我只想让IE也这么做。当你点击滚动条时,IE触发模糊事件,我也遇到了类似的问题。显然,它只发生在IE7及以下,IE8处于怪癖模式 这是我通过谷歌找到的东西 基本上

我有一个像下拉菜单一样的div。因此,当你点击一个按钮时,它会弹出,允许你滚动浏览这个大列表。因此div有一个垂直滚动条。如果在div外单击,即单击“模糊”,则div应消失


问题在于,当用户点击div的滚动条时,IE错误地触发了
onblur
事件,而Firefox没有。我猜Firefox仍然将滚动条视为div的一部分,我认为这是正确的。我只想让IE也这么做。

当你点击滚动条时,IE触发模糊事件,我也遇到了类似的问题。显然,它只发生在IE7及以下,IE8处于怪癖模式

这是我通过谷歌找到的东西


基本上,只有当您知道某人在文档上单击了当前焦点div以外的某个位置时,才可以进行模糊处理。可以反向检测滚动条的单击,因为当您单击滚动条时document.onclick不会触发。

我也遇到了同样的问题。解决方法是将菜单放在一个包装(更大)分区中。将模糊应用到包装上,效果很好

也许可以尝试将设置为
-1
tabindex
属性添加到
div
节点。

我在自动完成下拉列表中遇到了类似的滚动条问题。由于下拉列表应该在它所附加的表单元素失去焦点时隐藏,因此将焦点保持在正确的元素上成为一个问题。单击滚动条时,只有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上滚动条所属的元素。

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


迟交的答案,但我有同样的问题,目前的答案不适合我

popup元素的悬停状态按预期工作,因此在模糊事件中,您可以检查您的popup元素是否悬停,并且只有在不悬停时才将其删除/隐藏:

$('#element-with-focus').blur(function()
{
    if ($('#popup:hover').length === 0)
    {
        $('#popup').hide()
    }
}
您需要将焦点移回绑定了模糊事件的原始元素。这不会影响滚动:

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

这不适用于IE7或更低版本-所以只需放弃对它的支持


示例:

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

我收听菜单上的mousedown事件,并在此事件上设置一个标志。当我捕捉到模糊事件时,如果mousedown标志处于启用状态,我会将焦点设置回原来的位置。由于Edge、FF和Chrome不会触发模糊事件,但会触发mouseup事件(IE不会),因此我为它们重置了mouseup上的mousedown标志(IE的模糊)


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

我不认为这是IE的问题

这更多的是一个如何设计你的交互以及在哪里处理哪一个事件的案例。 如果相关目标具有唯一的css类访问器,则可以通过检查event.relatedTarget的类列表中要允许或不允许启动模糊事件的元素来取消模糊事件。在我的一个ES2015项目中的自定义自动完成下拉列表中查看我的onBlurHandler(对于较旧的JS支持,您可能需要解决
contains()
):

onBlurHandler(事件:FocusEvent){
if(event.relatedTarget
&&(event.relatedTarget作为HtmleElement).classList.contains('folding-select-result-list')){
//不允许从“.折叠选择结果列表”中出现任何模糊事件`
event.preventDefault();
}如果(!event.relatedTarget
||event.relatedTarget
&&!(event.relatedTarget作为HtmleElement)。classList.contains('select-item')){
//如果模糊事件来自外部(而不是“选择项”),请清除建议列表
//“.select item”的onClickHandler将清除使用此.clearAfterSelect配置的suggestList
this.clearOptions(this.clearAfterBlur);
}
}
  • .folding select result list
    是我的建议下拉列表,其中有“空点”和“可能有一个滚动条”,我不需要这个模糊事件
  • .select item
    有自己的onClickHandler,可以触发
    $('#popup').focus(function(e)
    {
        $('#element-with-focus').focus();
    });
    
      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;    
          } 
        },