Disabling click event handlers
I am trying to basically disable the click
event on a <div>
temporarily.
I have tried the following (preview):
$('hello').observe('click', function (e) {
e.stop();
});
$('hello').observe('click', function (e) {
alert('click not stopped!');
});
However, when #hello
is clicked, the alert box still appears. I do not want the second attached handler to be called, and I do not want to change the second handler.
I will also accept a solution such as:
$('hello').observe('click', function (e) {
alert('click not stopped!');
});
$('hello').disableEvent('click');
// Now, handler won't be called
$('hello').observe('click', function (e) {
alert('click not s开发者_JAVA技巧topped (2)!');
});
// New handler won't be called, either
$('hello').enableEvent('click');
// Now, handler will be called
I am using the Prototype.js framework. This doesn't seem to be a browser-specific issue.
When you assign handlers to events; you are basically just storing a set of functions to be executed when an event fires.
When an event fires, the handlers you've added are executed in the order they we're added. So if you we're to add three handlers to a div's click-event:
$("div").observe("click", function ()
{
alert("one");
});
$("div").observe("click", function ()
{
alert("two");
});
$("div").observe("click", function ()
{
alert("three");
});
.. you would get three alerts ("one", "two" and "three") when the click event of the div element fires. Those three alerts will still get shown, if you put in:
$("div").observe("click", function (e)
{
e.stop();
})
.. because you are only canceling the event for one particular handler. Not all associated handlers.
So what you will need to do is use a reference variable, which keeps track of wether the click event is allowed to fire:
var cancelClickEvent = true;
$("div").observe("click", function ()
{
// if cancelClickEvent is true, return the function early, to
// stop the code underneath from getting executed
if (cancelClickEvent) return;
// your code goes here
});
You will then need to implement the above if-clause in all your handlers.
Can't you just set the object's disabled property to true?
As I said in comments to roosteronacid's answer, I wrote an extension to Event.observe
. Works in most browsers, but not IE.
// XXX HACK XXX
(function () {
var handlerCache = $A([ ]);
function findHandler(either) {
var pair = handlerCache.find(function (pair) {
return $A(pair).member(either);
});
return pair && pair[0];
}
function addHandler(handler) {
function newHandler(e) {
if (!e.halted) {
handler.apply(this, arguments);
}
}
handlerCache.push([ handler, newHandler ]);
return newHandler;
}
Event.observe = Event.observe.extended(function ($super, element, eventName, handler) {
handler = findHandler(handler) || addHandler(handler);
$super(element, eventName, handler);
});
Event.stopObserving = Event.stopObserving.extended(function ($super, element, eventName, handler) {
handler = findHandler(handler) || handler;
$super(element, eventName, handler);
});
Element.addMethods({
observe: Event.observe
});
Event.prototype.halt = function () {
this.halted = true;
};
}());
Note: Function.prototype.extended
is a custom function which puts the original Event.observe
in as $super
.
精彩评论