停止传播不起作用

时间:2015-07-21 09:44:52

标签: javascript jquery javafx

我有以下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;
    });

当我在Facebook登录页面上使用它时,它会停止所有导航。但是在谷歌的主页上,“我很幸运”#34;按钮仍然导航到下一页。我该如何避免呢?

我顺便使用JavaFX浏览器。它类似于Safari浏览器。

8 个答案:

答案 0 :(得分:17)

如果我加载Google搜索页面,请在控制台执行此操作:

document.body.addEventListener(
  "click", 
  function (ev) { ev.stopPropagation(); ev.preventDefault(); },
  true);

然后我再也不能点击“我感觉很幸运”按钮了。关键是使用第三个参数并将其设置为true。以下是MDN [说]的内容:

  

useCapture可选

     

如果为true,则useCapture表示用户希望启动捕获。启动捕获后,指定类型的所有事件将被分派到已注册的侦听器,然后再分发到DOM树中它下面的任何EventTarget

(强调补充。)

您尝试做的事情不起作用,因为您的事件处理程序在document上,因此在文档子项上的任何事件处理程序之后将被称为。所以你的处理程序无法阻止任何事情。

useCapture设置为true,您可以在事件有机会传递给子元素之前对事件进行操作。我不知道如何让jQuery的事件处理程序以useCapture的方式工作。 Barmar的answer here说你不能使用jQuery来设置这样的处理程序。我倾向于相信他。

答案 1 :(得分:5)

99.99%的网页因为我评论的原因而无法通过停止事件传播来停止导航(在触发初始目标的所有处理程序之前,您无法停止事件事件)。如果你感兴趣的是阻止导航,我推荐使用window.onbeforeunload事件,这是针对这种情况做的。

以下是一个示例:http://jsfiddle.net/ejreseuu/

HTML:

<a href="google.com">google</a>

JS:

window.onbeforeunload = function() {
    return "Are you sure?"
}

没有办法没有我知道的确认框,因为无论他们做什么通常都是恶意的,导致用户无法导航的代码。

答案 2 :(得分:0)

试试这个:

$('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;
    });

答案 3 :(得分:0)

尝试不仅绑定click事件,还绑定mousedown事件。

答案 4 :(得分:0)

试试这个css:

 body * {
    pointer-events: none;
 }

或在jQuery中:

 $("body *").css("pointer-events", "none");

答案 5 :(得分:0)

尝试声明一个新窗口事件,然后从那里停止传播:

var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation)
{
   e.stopPropagation();
}

答案 6 :(得分:0)

请注意,Google使用jsaction="..."代替onclick =&#34; ...&#34;。尝试在指定按钮上使用它的unbind方法。

您也可以使用动态附件,例如:

$(document).on('click', '*', function

throw new Error()(就像肮脏的黑客一样)

答案 7 :(得分:0)

在这种情况下,

preventDefault()不起作用,因为Google依靠自定义事件侦听器来处理此按钮上的点击事件。而preventDefault() 阻止浏览器的默认行为。

例如,如果此按钮的类型为“”submit“,则阻止Click事件的默认操作会阻止浏览器的默认行为,即提交表单。但在这种情况下,click由添加到按钮本身的eventListeners处理。 preventDefault()不会影响它们捕获事件。也不是stopPropagation(),因为它阻止事件传播到更高级别的DOM,而同一级别的其他eventListeners(在我们的例子中是按钮)仍然得到事件。 stopImmediatePropagation()可以在理论上起作用,但前提是你在google之前添加了eventListener。

因此,停止传播的最简单方法是在事件到达按钮节点之前停止事件,这是在捕获阶段,因为按钮是层次结构中的最低元素。这可以通过在添加eventListener

时传递 true 参数来完成
document.body.addEventListener("click", function (event) { 
  event.stopPropagation();
}, true);

这种方式事件将在冒泡阶段之前停止,因此在它到达添加到按钮的eventListeners之前。有关捕获和泡沫阶段的更多信息here

请注意,在这种情况下不需要preventDefault()。实际上,这个按钮的事件监听器是为了防止自己默认。以下是clickListeners,分别用于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)
}

请注意s_1vb,这是它的话:

s_1vb.toString();
/*"function (a){
     a&&(a.preventDefault&&a.preventDefault(),a.returnValue=!1);
     return!1
  }"*/

基本上它是一个接受事件并尽一切可能阻止浏览器默认行为的函数

顺便说一句,默认行为可以在任意阶段的事件流(se Events Specification)上取消,包括最后一个阶段,当它到达 document 。只有在它通过“通过”所有eventListeners没有取消后,浏览器才会执行其默认行为。所以将你的监听器附加到文档并不是preventDefault()不起作用的原因,这是因为这是错误的工作:)