简体   繁体   English

模糊事件阻止点击事件工作?

[英]Blur event stops click event from working?

It appears that the Blur event stops the click event handler from working?似乎 Blur 事件停止了单击事件处理程序的工作? I have a combo box where the options only appear when the text field has focus.我有一个组合框,其中选项仅在文本字段具有焦点时出现。 Choosing an option link should cause an event to occur.选择一个选项链接应该会导致一个事件发生。

I have a fiddle example here: http://jsfiddle.net/uXq5p/6/我在这里有一个小提琴示例: http : //jsfiddle.net/uXq5p/6/

To reproduce:重现:

  1. Select the text box选择文本框
  2. Links appear出现链接
  3. Click a link点击链接
  4. The blur even occurs and the links disappear甚至会出现模糊并且链接消失
  5. Nothing else happens.没有其他事情发生。

Expected behavior:预期行为:

On step 5, after blur occurs, the click even should also then fire.在第 5 步,模糊发生后,点击事件也应该触发。 How do I make that happen?我该如何做到这一点?

UPDATE:更新:

After playing with this for a while, it seems that someone has gone to great lengths to prevent an already-occurred click event from being handled if a blur event makes the clicked element Un-clickable.在玩了一段时间之后,如果模糊事件使被点击的元素不可点击,似乎有人已经竭尽全力阻止已经发生的点击事件被处理。

For example:例如:

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

works just fine, but工作得很好,但是

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

prevents the click event.防止点击事件。

This appears to be a bug in Firefox, since making an element un-clickable should prevent future clicks, but not cancel ones that have already occurred when it could be clicked.这似乎是 Firefox 中的一个错误,因为使元素不可点击应该可以防止将来的点击,但不会取消可以点击时已经发生的点击。

Other things that prevent the click event from processing:其他阻止点击事件处理的事情:

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

I've found a few other questions on this site that are having similar problems.我在这个网站上发现了其他一些有类似问题的问题。 There seem to be two solutions floating around:似乎有两种解决方案:

  1. Use a delay.使用延迟。 This is bad because it creates a race condition between the hiding and the click event handler.这很糟糕,因为它在隐藏和单击事件处理程序之间创建了竞争条件。 Its also sloppy.它也很草率。

  2. Use the mousedown event.使用mousedown事件。 But this isn't a great solution either since click is the correct event for a link.但这也不是一个很好的解决方案,因为click链接的正确事件。 The behavior of mousedown is counter-intuitive from a UX perspective, particularly since you can't cancel the click by moving the mouse off the element before releasing the button.从用户体验的角度来看, mousedown的行为是违反直觉的,特别是因为您无法通过在释放按钮之前将鼠标移离元素来取消单击。

I can think of a few more.我还能想到几个。

3.Use mouseover and mouseout on the link to enable/disable the blur event for the field. 3.在链接上使用mouseovermouseout来启用/禁用该字段的模糊事件。 This doesn't work with keyboard tabing since the mouse is not involved.由于不涉及鼠标,因此这不适用于键盘选项卡。

4.The best solution would be something like: 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.
}

Unfortunately, $(document.activeElement) seems to always return the body element, not the one that was clicked.不幸的是, $(document.activeElement)似乎总是返回 body 元素,而不是被点击的那个。 But maybe if there was a reliable way to know either 1. which element now has focus or two, which element caused the blur (not which element is blurring) from within the blur handler.但也许如果有一种可靠的方法可以从模糊处理程序中知道 1. 哪个元素现在具有焦点或两个焦点,哪个元素导致了模糊(而不是哪个元素正在模糊)。 Also, is there any other event (besides mousedown ) that fires before blur?另外,是否还有其他事件(除了mousedown )在模糊之前触发?

click event triggers after the blur so the link gets hidden. click事件在blur后触发,因此链接被隐藏。 Instead of click use mousedown it will work.而不是click使用mousedown它会起作用。

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

Other alternative is to have some delay before you hide the links on blur event.另一种选择是在隐藏blur事件的链接之前有一些延迟。 Its upto you which approach to go for.由您决定采用哪种方法。

Demo演示

You could try the mousedown event instead of click .您可以尝试使用mousedown事件而不是click

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

This is clearly not the best solution as a mousedown event is not achieved the same way for the user than a click event.这显然不是最好的解决方案,因为对于用户来说, mousedown事件的实现方式与click事件的实现方式不同。 Unfortunately, the blur event will cancel out mouseup events as well.不幸的是, blur事件也会取消mouseup事件。

Performing an action that should happen on a click on a mousedown is bad UX.执行应该在click mousedown发生的操作是糟糕的用户体验。 Instead, what's a click effectively made up of?相反, click有效地由什么组成? A mousedown and a mouseup .一个mousedown和一个mouseup

Therefore, stop the propagation of the mousedown event in the mousedown handler, and perform the action in the mouseup handler.因此,在mousedown处理程序中停止mousedown事件的传播,并在mouseup处理程序中执行操作。

An example in ReactJS: ReactJS 中的一个例子:

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

4.The best solution would be something like: 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. }

Unfortunately, $(document.activeElement) seems to always return the body element, not the one that was clicked.不幸的是, $(document.activeElement) 似乎总是返回 body 元素,而不是被点击的那个。 But maybe if there was a reliable way to know either 1. which element now has focus or two, which element caused the blur (not which element is blurring) from within the blur handler.但也许如果有一种可靠的方法可以从模糊处理程序中知道 1. 哪个元素现在具有焦点或两个焦点,哪个元素导致了模糊(而不是哪个元素正在模糊)。

What you may be looking for is e.relatedTarget .您可能正在寻找的是e.relatedTarget So when clicking the link, e.relatedTarget should get populated with the link element, so in your blur handler, you can choose not to hide the container if the element clicked is within the container (or compare it directly with the link):因此,当单击链接时, e.relatedTarget应填充链接元素,因此在您的模糊处理程序中,如果单击的元素在容器内(或直接与链接进行比较),您可以选择不隐藏容器:

$('#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 may not be supported in older browsers for blur events, but it appears to work in latest Chrome, Firefox, and Safari) (对于blur事件,旧浏览器可能不支持relatedTarget ,但它似乎适用于最新的 Chrome、Firefox 和 Safari)

If this.menuTarget.classList.add("hidden") is the blur behavior that hides the clickable menu, then I succeeded by waiting 100ms before invoking it.如果this.menuTarget.classList.add("hidden")是隐藏可点击菜单的模糊行为,那么我在调用它之前等待 100 毫秒就成功了。

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

This allowed the click event to be processed upon the menuTarget DOM before it was hidden.这允许在menuTarget DOM 隐藏之前处理单击事件。

I know this is a later reply, but I had this same issue, and a lot of these solutions didn't really work in my scenario.我知道这是后来的回复,但我遇到了同样的问题,而且很多这些解决方案在我的场景中并没有真正起作用。 mousedown is not functional with forms, it can cause the enter key functionality to change on the submit button. mousedown对表单不起作用,它可能导致提交按钮上的输入键功能发生变化。 Instead, you can set a variable _mouseclick true in the mousedown , check it in the blur , and preventDefault() if it's true.相反,您可以在mousedown设置一个变量_mouseclick true ,在blur检查它,如果为 true 则preventDefault() Then, in the mouseup set the variable false.然后,在mouseup设置变量 false。 I did not see issues with this, unless someone can think of any.我没有看到这方面的问题,除非有人能想到任何问题。

I have faced a similar issue while using jQuery blur, click handlers where I had an input name field and a Save button.我在使用 jQuery 模糊、单击处理程序时遇到了类似的问题,其中我有一个输入名称字段和一个保存按钮。 Used blur event to populate name into a title placeholder.使用模糊事件将名称填充到标题占位符中。 But when we click save immediately after typing the name, only the blur event gets fired and the save btn click event is disregarded.但是,当我们在输入名称后立即单击保存时,只会触发模糊事件,而忽略保存 btn 单击事件。

The hack I used was to tap into the event object we get from blur event and check for event.relatedTarget.我使用的技巧是利用我们从模糊事件中获得的事件对象并检查 event.relatedTarget。

PFB the code that worked for me: PFB 对我有用的代码:

$("#inputName").blur(function (event) {
        title = event.target.value;
        //since blur stops an immediate click event from firing - Firing click event here
        if (event.relatedTarget ? event.relatedTarget.id == "btnSave" : false) {
            saveBtn();
        }
    });

$("#btnSave").click(SaveBtn)

As already discussed in this thread - this is due to blur event blocking click event when fired simultaneously.正如本线程中已经讨论的那样 - 这是由于同时触发时模糊事件阻塞了单击事件。 So I have a click event registered for Save Btn calling a function which is also called when blur event's related Target is the Save button to compensate for the click event not firing.因此,我为 Save Btn 注册了一个单击事件,该函数调用了一个函数,当模糊事件的相关目标是 Save 按钮以补偿未触发的单击事件时,也会调用该函数。 Note: Didnt notice this issue while using native onclick and onblur handlers - tested in html.注意:在使用原生 onclick 和 onblur 处理程序时没有注意到这个问题 - 在 html 中测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM