模糊事件会使点击事件停止工作吗?


72

看来,模糊事件会使click事件处理程序停止工作吗?我有一个组合框,其中的选项仅在文本字段具有焦点时出现。选择一个选项链接应该导致一个事件发生。

我在这里有一个小提琴的例子:http : //jsfiddle.net/uXq5p/6/

复制:

  1. 选择文本框
  2. 出现链接
  3. 点击链接
  4. 甚至发生模糊并且链接消失
  5. 什么都没发生。

预期行为:

在第5步中,在发生模糊之后,咔嗒声甚至也应该触发。我该如何实现?

更新:

在玩了一段时间之后,如果模糊事件使clicked元素变为Un-clickable,似乎有人已经竭尽全力防止已经发生的click事件得到处理。

例如:

$('#ShippingGroupListWrapper').css('left','-20px');

效果很好,但是

$('#ShippingGroupListWrapper').css('left','-2000px');

防止点击事件。

这似乎是在Firefox中的错误,因为让一个元素未点击应防止未来的点击,但没有取消的时候可以点击它已经发生的。

阻止click事件处理的其他原因:

$('#ShippingGroupListWrapper').css('z-index','-20');
$('#ShippingGroupListWrapper').css('display','none');
$('#ShippingGroupListWrapper').css('visibility','hidden');
$('#ShippingGroupListWrapper').css('opacity','.5');

我在这个网站上发现了其他一些类似的问题。似乎有两种解决方案:

  1. 使用延迟。这很糟糕,因为它在隐藏事件和单击事件处理程序之间创建了竞争条件。它也马虎。

  2. 使用mousedown事件。但这也不是一个很好的解决方案,因为这click 链接的正确事件。mousedown从UX的角度来看,行为是违反直觉的,尤其是因为您不能通过在释放按钮之前将鼠标移离元素来取消单击。

我还能想到更多。

3.在链接上使用mouseover和启用/禁用字段的模糊事件。由于不涉及鼠标,因此这不适用于键盘制表键。mouseout

4.最好的解决方案是这样的:

$('#ShippingGroup').blur(function()
{
   if($(document.activeElement) == $('.ShippingGroupLinkList'))
      return; // The element that now has focus is a link, do nothing
   $('#ShippingGroupListWrapper').css('display','none'); // hide it.
}

不幸的是,$(document.activeElement)似乎总是返回body元素,而不是被单击的元素。但是,也许有一种可靠的方法可以知道1.现在哪个元素具有焦点或两个焦点,哪个元素从模糊处理程序中引起了模糊(不是哪个元素正在模糊)。另外,还有其他事件(除了之外mousedown)会在模糊之前触发?


4
问题是模糊事件在单击之前触发。由于模糊隐藏了这些元素,因此最终您什么也没有点击。
vcsjones 2012年

1
我不确定隐藏是问题所在。我尝试将不透明度设置为50%,而不是隐藏它们,并且单击事件仍然不会发生。请参阅jsfiddle.net/75sgt/1
尼克(Nick)

经过进一步的实验,正是新的非公开性可追溯地“取消点击”已经点击的元素。请参阅上面的更新。
尼克

Answers:


90

click事件在触发后触发,blur因此链接被隐藏。代替click使用mousedown它将起作用。

$('.ShippingGroupLinkList').live("mousedown", function(e) {
    alert('You wont see me if your cursor was in the text box');
});

另一种选择是在隐藏blur事件链接之前有一些延迟。由您决定采用哪种方法。

演示版


1
使用延迟很危险。应该坚持与mousedown。
马歇尔

是的,即使我总是选择使用,mousedown而不要使用肮脏的延迟逻辑。
ShankarSangoli 2012年

延误是不好的,因为...它会造成竞争状况?因此,问题不在于单击在模糊后甚至不会触发,而是单击事件不会在“ display:none”元素上触发吗?如果链接显示为opacity:0或类似值,而不是display:none怎么办?
尼克

7
另请注意:这也会在右键单击时触发,通常不会触发该单击。您的管理员应包括if (e.which === 1) { }
Brad

2
小心。您确定这对不使用鼠标激活链接或聚焦/模糊元素的用户有用吗?
Michael Scheper

5

您可以尝试使用该mousedown活动代替click

$('.ShippingGroupLinkList').live("mousedown", function(e) {
    alert('You wont see me if your cursor was in the text box');
});

显然,这不是最佳解决方案,因为mousedown对于用户而言,与click事件相比,事件的实现方式不同。不幸的是,该blur事件也会取消mouseup事件。


我相信将鼠标按下会触发模糊。另一种选择是防止在mousedown上传播并在mouseup上执行操作。
Nate Symer

2

执行应在aclick上执行的操作mousedown是错误的UX。相反,click有效组成的是什么?一mousedownmouseup

因此,请停止mousedownmousedown处理程序中传播事件,并在处理程序中执行操作mouseup

ReactJS中的一个示例:

<a onMouseDown={e => e.preventDefault()}
   onMouseUp={() => alert("CLICK")}>
   Click me!
</a>

1

4.最好的解决方案是这样的:

$('#ShippingGroup').blur(function()
{
   if($(document.activeElement) == $('.ShippingGroupLinkList'))
      return; // The element that now has focus is a link, do nothing
   $('#ShippingGroupListWrapper').css('display','none'); // hide it.
}

不幸的是,$(document.activeElement)似乎总是返回body元素,而不是被单击的元素。但是,也许有一种可靠的方法可以知道1.现在哪个元素具有焦点或两个焦点,哪个元素从模糊处理程序中引起了模糊(不是哪个元素正在模糊)。

您可能正在寻找的是e.relatedTarget。因此,在单击链接时,e.relatedTarget应填充link元素,因此在模糊处理程序中,如果单击的元素在容器内(或直接将其与链接进行比较),则可以选择不隐藏容器:

$('#ShippingGroup').blur(function(e)
{
   if(!e.relatedTarget || !e.currentTarget.contains(e.relatedTarget)) {
   // Alt: (!e.relatedTarget || $(e.relatedTarget) == $('.ShippingGroupLinkList'))

       $('#ShippingGroupListWrapper').css('display','none'); // hide it.
   }
}

relatedTarget较早的浏览器可能不支持blur事件播放,但似乎可以在最新的Chrome,Firefox和Safari中使用)


1

如果this.menuTarget.classList.add("hidden")是隐藏可点击菜单的模糊行为,那么我在调用它之前先等待了100ms。

setTimeout(() => {
  this.menuTarget.classList.add()
}, 100)

这样就可以在menuTarget隐藏DOM之前对其进行处理。


延迟也为我工作。因为我使用的是routerLink,而不是onclick ...
mamashare '20

0

我知道这是以后的答复,但是我遇到了同样的问题,其中许多解决方案在我的情况下并没有真正起作用。mousedown不适用于表格,它可能导致输入键功能在“提交”按钮上发生更改。相反,您可以在中将变量设置为_mouseclicktrue,在中将其mousedown检查blurpreventDefault()如果为true。然后,在mouseup设置变量false。我没有看到与此相关的问题,除非有人能想到任何问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.