简体   繁体   English

如何从纯JavaScript代码中取消jQuery.click?

[英]How to cancel jQuery.click from pure javascript code?

To make it simple: 为了简单起见:

I have a webpage. 我有一个网页。 It has some scripts, one of which bind a click event to an <a> tag. 它具有一些脚本,其中之一将click事件绑定到<a>标记。

$('#someId').click(function() {
    ......
});

I want to add a pure javascript to this page (I'm not allowed to modify other js files) and take control of the click event. 我想在此页面上添加纯JavaScript (不允许我修改其他js文件)并控制click事件。 What I have tried is as follows: 我尝试过如下:

document.getElementById('someId').onclick = function (event) {
    if (someCondition) {
        // cancel this click event 
        event.preventDefault();
        event.stopPropagation();
        event.cancel = true;
        return false;
    } else {
        // do something else.
    }
};

This piece of code seems not working. 这段代码似乎不起作用。 I need some help. 我需要协助。

UPDATE UPDATE

Sorry for my ambiguous language. 对不起,我的语言含糊不清。 By "pure javascript" I mean "using basic javascript manipulations instead of jQuery methods." “纯javascript”是指“使用基本的javascript操作而不是jQuery方法。”

I want to add a pure javascript to this page (I'm not allowed to modify other js files) and take control of the click event. 我想在此页面上添加纯JavaScript(不允许我修改其他js文件)并控制click事件。

If the code is going to be on that page, it can use jQuery, which is good because that's also the only way you can unregister the jQuery-registered handler: 如果代码将在该页面上,它可以使用jQuery,这很好,因为这也是注销jQuery注册处理程序的唯一方法:

$("#someId").off("click").on("click", function() {
    // Your new code here
});

Calling .off("click") on an element removes all jQuery-registered click handlers from that element. 在元素上调用.off("click")从该元素中删除所有 jQuery注册的click处理程序。

That said, usually there's a better approach than clobbering the handlers registered by other code on the page. 就是说,通常有比掩盖页面上其他代码注册的处理程序更好的方法。


Why you can't unregister the jQuery-registered handler without using jQuery: The first time a particular event is hooked on a particular element via jQuery, jQuery registers one handler (its own) to use for that event on that element; 为什么不使用jQuery就无法注销jQuery注册的处理程序:第一次通过jQuery将特定事件挂接到特定元素时,jQuery在该元素上注册了一个处理程序(自己使用),用于该事件。 if more handlers are attached, it just adds them to its own internal list, it doesn't register those with the DOM. 如果附加了更多处理程序,则只会将它们添加到自己的内部列表中,而不会在DOM中注册这些处理程序。 Instead, when the DOM event is fired, jQuery walks through its list of handlers and triggers them. 相反,当触发DOM事件时,jQuery遍历其处理程序列表并触发它们。

To unregister jQuery's actual handler for the event on the element, you'd have to get a reference to the specific function instance jQuery used when registering it. 要为元素上的事件取消注册jQuery的实际处理程序,您必须获得对jQuery注册时使用的特定函数实例的引用。 ( removeEventListener doesn't have the equivalent of the above "clear all of them"). removeEventListener不具有上述“清除所有内容”的等效项)。 That reference is only available from data structures inside jQuery's closure, so you can't get at it without using jQuery. 引用仅可从jQuery闭包内部的数据结构中获得,因此如果不使用jQuery,您将无法获得引用。


What should I do if other handlers need to resume to be executed under some circumstances in the $.on() block? 如果某些情况下需要在$ .on()块中继续执行其他处理程序,该怎么办?

Ah, that's much more difficult. 啊,这要困难得多。 It all depends on more of the context than is present in your question. 这完全取决于您所提出的问题之外的更多上下文。 Some options: 一些选项:

  1. By far the best thing is to modify the other code that is handling clicks. 到目前为止,最好的办法是修改其他处理点击的代码。 But I understand you're saying you can't do that. 但我知道您是说您无法做到这一点。

  2. jQuery calls handlers in the order they were registered (this is one reason it handles calling multiple handlers itself; different browsers do things in different orders). jQuery按照注册时的顺序调用处理程序(这是它自己处理调用多个处理程序的原因之一;不同的浏览器按不同的顺序执行操作)。 So if you can hook click on #someId before the other code does, then you can reliably use event.stopImmediatePropagation() to prevent other handlers from being called. 因此,如果您可以在其他代码之前 click #someId ,则可以可靠地使用event.stopImmediatePropagation()来防止调用其他处理程序。 That won't work, of course, if your handler isn't first in the list, because the other handlers will have been called first. 当然,如果您的处理程序不在列表中的第一位,那将是行不通的,因为其他处理程序将首先被调用。

  3. If there's an element within the #someId element that completely fills it, you can hook click on that element instead, and then use event.stopPropagation() to prevent the event from bubbling up to the #someId element. 如果#someId元素中有一个元素完全填充了该元素,则可以钩住元素的click ,然后使用event.stopPropagation()防止事件冒泡到#someId元素中。

  4. And of course, if there isn't an element like #3, you could probably insert one (dynamically, with code) and move #someId 's contents into it, so you could inject your handler into the bubbling. 当然,如果没有像#3这样的元素,则可以(通过代码动态地)插入一个元素并将#someId的内容移入其中,以便将处理程序注入到冒泡中。

  5. You can dive into jQuery's internals and figure out how to access the event handler chain and manipulate it. 您可以深入研究jQuery的内部原理,并弄清楚如何访问事件处理程序链并进行操作。 It used to be quite easy; 过去很简单; I think recent versions have made it harder. 我认为最新版本使它变得更加困难。 This would be, of course, going into undocumented territory that could change with any "dot" release. 当然,这将进入未记录的领域,并且可能会随“ dot”版本的发布而改变。

There is one more possible solution, but unfortunately it has some browser compatibility issues. 还有另一种可能的解决方案,但不幸的是,它存在一些浏览器兼容性问题。 The point is to use css pointer-events property and onmousedown event like this: 关键是使用css pointer-events属性和onmousedown事件,如下所示:

$('a').click(function() {
    alert('jquery');
});

var i = 0;
btn.onmousedown = function(ev) {
    if (i++ % 2 == 0) {
        btn.style.pointerEvents = 'none'; // disable clicks

        setTimeout(function() {
            btn.style.pointerEvents = 'auto'; // enable back in 500 ms
        }, 500);
    }
};

See compatibility here and the demo is here 在此处查看兼容性并在此处演示

For IE you can try element disabled property in a same way. 对于IE,您可以通过相同的方式尝试元素disabled属性。

And sure it's better to use jQuery for this (if it is used already in your project) 并且确保最好为此使用jQuery(如果您的项目中已经使用过jQuery)

You need to add the click listener after the page has loaded. 页面加载后,您需要添加点击监听器。

window.onload=function(){
    //your code here.
};

If you are trying to disable the button after the click, add the 'disabled' property to the button and remove the click listener. 如果您尝试在单击后禁用按钮,请将“ disabled”属性添加到按钮并删除单击侦听器。

document.getElementById('someId').onclick = null;
document.getElementById('someId').disabled = true;

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

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