javascript 停止传播不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31535600/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Stop propagation doesn't work
提问by NaveenBharadwaj
I have the below JQuery eventhandler
. I want to stop all navigations on a web page.
我有以下 JQuery eventhandler
。我想停止网页上的所有导航。
$(document).click(function(event) {
event.stopPropagation();
event.preventDefault();
event.cancelBubble = true;
event.stopImmediatePropagation();
$(document).css('border-color','');
$(document).css('background-color','');
$(event.target).css('border-color','yellow');
$(event.target).css('background-color','#6BFF70');
return false;
});
When I use this on Facebook Login page, it stops all navigations. But in Google home page, "I'm Feeling Lucky" button still navigates to next page. How do I avoid it?
当我在 Facebook 登录页面上使用它时,它会停止所有导航。但是在 Google 主页中,“手气不错”按钮仍会导航到下一页。我该如何避免?
I'm using JavaFX browser by the way. It is similar to Safari browser.
顺便说一下,我正在使用 JavaFX 浏览器。它类似于 Safari 浏览器。
回答by Louis
If I load the Google search page, and execute this at the console:
如果我加载 Google 搜索页面,并在控制台执行此操作:
document.body.addEventListener(
"click",
function (ev) { ev.stopPropagation(); ev.preventDefault(); },
true);
then I cannot click the "I'm Feeling Lucky" button anymore. The key is to use the third parameter and set it to true
. Here is what MDN [says] about it:
那么我就不能再点击“我感觉很幸运”按钮了。关键是使用第三个参数并将其设置为true
. 这是 MDN [说] 关于它的内容:
useCapture
OptionalIf true,
useCapture
indicates that the user wishes to initiate capture. After initiating capture, all events of the specified type will be dispatched to the registered listener before being dispatched to anyEventTarget
beneath it in the DOM tree.
useCapture
选修的如果为真,则
useCapture
表示用户希望启动捕获。启动捕获后,指定类型的所有事件将被分派到注册的侦听器,然后再分派到EventTarget
DOM 树中它下面的任何事件。
(Emphasis added.)
(加了重点。)
What you tried to do does not work because your event handler is on document
, and thus will be called afterany event handlers on the children of the document. So your handler cannot prevent anything.
您尝试执行的操作不起作用,因为您的事件处理程序是 on document
,因此将在文档子项上的任何事件处理程序之后调用。所以你的处理程序不能阻止任何事情。
With useCapture
set to true, you can operate on the event before it gets a chance to be passed to the child element. I do not know of a way to have jQuery's event handlers work in the way you get with useCapture
. Barmar's answer heresays you can't use jQuery to set such handler. I'm inclined to believe him.
随着useCapture
设置为true,就可以得到它要传递给子元素的机会之前,对事件进行操作。我不知道有什么方法可以让 jQuery 的事件处理程序以您使用useCapture
. Barmar's answer here说你不能使用 jQuery 来设置这样的处理程序。我倾向于相信他。
回答by Tahsis Claus
99.99% of webpages won't be able to have their navigation stopped by stopping event propagation for the reason I commented (you can't stop the event before it triggers all handlers for the initial target of the event). If preventing navigation is all you are interested in, I recommend using the window.onbeforeunload event, which is made for this exact situation.
由于我评论的原因,99.99% 的网页将无法通过停止事件传播来停止导航(您无法在事件触发事件初始目标的所有处理程序之前停止事件)。如果您只对阻止导航感兴趣,我建议您使用 window.onbeforeunload 事件,该事件专为这种情况而设计。
Here is an example: http://jsfiddle.net/ejreseuu/
这是一个例子:http: //jsfiddle.net/ejreseuu/
HTML:
HTML:
<a href="google.com">google</a>
JS:
JS:
window.onbeforeunload = function() {
return "Are you sure?"
}
There is no way to not have a confirmation box that I know of, as code that locks the user out of navigating away no matter what they do is generally malicious.
我所知道的没有确认框是不可能的,因为无论用户做什么,都会将用户锁定在导航之外的代码通常是恶意的。
回答by Pavlo D
preventDefault() should not work in this case, cause Google relied on custom event listenersto handle click events on this button. While preventDefault() prevents browser'sdefault behavior.
在这种情况下, preventDefault() 不应该起作用,因为 Google 依赖自定义事件侦听器来处理此按钮上的点击事件。而 preventDefault() 阻止浏览器的默认行为。
For example, if this button was of type="submit", preventing default on click event would prevent browser's default behavior, which is submitting a form. But in this case click is handled by eventListeners added to the button itself. preventDefault() won't affect catching an event by them. Nor stopPropagation(), because it stops propagation of event to higher levels of DOM, while other eventListeners on the same level (button in our case) still get the event. stopImmediatePropagation() could work in theory, but only if your eventListener was added before google's.
例如,如果此按钮的类型为 =“提交”,则阻止默认点击事件将阻止浏览器的默认行为,即提交表单。但在这种情况下,单击由添加到按钮本身的 eventListeners 处理。preventDefault() 不会影响它们捕获事件。也不是 stopPropagation(),因为它停止将事件传播到更高级别的 DOM,而同一级别上的其他 eventListeners(在我们的例子中是按钮)仍然获得事件。stopImmediatePropagation() 理论上可以工作,但前提是您的 eventListener 在 google 之前添加。
So the easiest way to stop propagation is to stop an event before it reaches button node, and that's on capture phase, because button is the lowest element in the hierarchy. This can be done by passing trueargument while adding eventListener
所以停止传播的最简单方法是在事件到达按钮节点之前停止事件,这是在捕获阶段,因为按钮是层次结构中的最低元素。这可以通过在添加 eventListener 时传递true参数来完成
document.body.addEventListener("click", function (event) {
event.stopPropagation();
}, true);
This way event will be stopped before bubble phase, and so before it reaches eventListeners added to the button. More on capture and bubble phases here
这样事件将在冒泡阶段之前停止,因此在它到达添加到按钮的 eventListeners 之前。更多关于捕获和气泡阶段的信息在这里
Note that preventDefault() is not needed in this case. Actually, this button's event listeners are to prevent default themselves. Here are those eventListeners, for click and keyup respectively:
请注意,在这种情况下不需要 preventDefault()。实际上,这个按钮的事件监听器是为了防止默认。以下是分别用于 click 和 keyup 的事件监听器:
d = function(a) {
c.Xa.search(c.yc(), b);
return s_1vb(a)
}
function(a) {
13 != a.keyCode && 32 != a.keyCode || d(a)
}
note call to s_1vb, here is its sourse:
注意对 s_1vb 的调用,这是它的来源:
s_1vb.toString();
/*"function (a){
a&&(a.preventDefault&&a.preventDefault(),a.returnValue=!1);
return!1
}"*/
Basically its a function that take an event and do everything possible to prevent browser's default behavior
基本上它是一个函数,它接受一个事件并尽一切可能阻止浏览器的默认行为
By the way, default behavior can be canceled on any stageof event flow (se Events Specification), including the very last stage, when it reached document. Only after it passed "through" all eventListeners uncanceled, browser should execute its default behavior. So attaching your listener to document was not the reason preventDefault() didn't work, it was because it was the wrong guy for the job :)
顺便说一下,默认行为可以在事件流的任何阶段(请参阅Events Specification)取消,包括最后一个阶段,当它到达document 时。只有在“通过”所有未取消的事件侦听器之后,浏览器才应执行其默认行为。因此,将您的侦听器附加到文档并不是 preventDefault() 不起作用的原因,而是因为它不适合这份工作:)
回答by kimwz.kr
Try this:
试试这个:
$('body').click(function(event) {
event.stopPropagation();
event.preventDefault();
event.cancelBubble = true;
event.stopImmediatePropagation();
$(document).css('border-color','');
$(document).css('background-color','');
$(event.target).css('border-color','yellow');
$(event.target).css('background-color','#6BFF70');
return false;
});
回答by Catalin
Try to bind not only to click
event, but as well on mousedown
event.
尝试不仅绑定到click
事件,还绑定到mousedown
事件。
回答by tnt-rox
Try this css:
试试这个css:
body * {
pointer-events: none;
}
or in jQuery:
或在 jQuery 中:
$("body *").css("pointer-events", "none");
回答by Skytiger
Try declaring a new window event and then stopping the propagation from there:
尝试声明一个新的窗口事件,然后从那里停止传播:
var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation)
{
e.stopPropagation();
}
回答by ScorpioT1000
Note that Google uses jsaction="..."instead of onclick="...". Try to use it's unbind method on the specified button.
请注意,Google 使用jsaction="..."而不是 onclick="..."。尝试在指定的按钮上使用它的 unbind 方法。
Also you can use dynamic attachment, like:
您也可以使用动态附件,例如:
$(document).on('click', '*', function
Or throw new Error()
(just as a dirty hack)
或者throw new Error()
(就像一个肮脏的黑客)