[英]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:重现:
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:
似乎有两种解决方案:
Use a delay.使用延迟。 This is bad because it creates a race condition between the hiding and the click event handler.
这很糟糕,因为它在隐藏和单击事件处理程序之间创建了竞争条件。 Its also sloppy.
它也很草率。
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.在链接上使用
mouseover
和mouseout
来启用/禁用该字段的模糊事件。 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.由您决定采用哪种方法。
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.