开发者

Event removal in Mootools, and syntax of event addition

So I have been adding my events thusly:

element.addEvent('click', function() {
    alert('foobar');
});

However, when attempting to remove said event, this syntactically identical code (with "add" switched to "remove") does not work.

element.removeEvent('click', function() {
    alert('foobar');
});

I assume this is because the two functions defined are not referenced the same, so the event is not technically removed. Alright, so I redefine the event addition and removal:

element.addEvent('click', alert('foobar'));
element.removeEvent('click', alert('foobar'));

Which works great, except now when the 开发者_JAVA技巧page loads, the click event is fired even before it's clicked!

The function is removed, though, which is great......


update: when you do .addEvent('type', function(){ }) and .removeEvent('type', function(){ }), even though the functions may have the same 'signatures', they are two separte anonymous functions, assigned on the fly. function 1 is !== to function 2 - hence there is no match when MooTools tries to remove it.

to be able to remove an exact handler, o:

function handler(){ ... } el.addEvent('click', handler); // .. later el.removeEvent('click', handler);

Internally, events are actually a map of keys to functions in element storage. have a look at this fiddle i did a while back for another SO question - http://www.jsfiddle.net/mVJDr/

it will check to see how many events are stacked up for a particular event type on any given element (or all events).

similarly, removeEvent looks for a match in the events storage - have a look on http://jsfiddle.net/dimitar/wLuY3/1/. hence, using named functions like Nikolaus suggested allows you to remove them easily as it provides a match.

also, you can remove events via element.removeEvents("click") for all click events.

your page now alerts because you pass on alert as the function as well as execute it with the params 'foobar'. METHOD followed by () in javascript means RUN THE METHOD PRECEDING IT IMMEDIATELY, NOT LATER. when you bind functions to events, you pass the reference (the method name) only.

to avoid using an anonymous function and to pass argument,s you can do something like:

document.id('foobar').addEvent('click', alert.bind(this, 'foo'));

as bind raps it for you, but removing this will be even more complicated.

as for event delegation, it's:

parentEl.addEvents({
    "click:relay(a.linkout)": function(e, el) {

    },
    "mouseover:relay(li.menu)": function(e, el) {

    }
});

more on that here http://mootools.net/docs/more/Element/Element.Delegation#Element:removeEvent

keep in mind it's not great / very stable. works fine for click stuff, mouseenter is not to be used delegated, just mouseover - which means IE can fire mouseout when it should not. the way i understand it, it's coming improved in mootools 2.0

edit updating to show an example of bound and unbound method within a class pattern in mootools

http://www.jsfiddle.net/wmhgw/

var foo = new Class({
    message: "hi",
    toElement: function() {
        return this.element = new Element("a", {
            href: "http://www.google.com",
            text: "google",
            events: {
                "click": this.bar.bind(this), // bind it
                "mouseenter": this.bar // unbound -> this.element becomes this
            }
        });

    },
    bar: function(event) {
        event.stop();
        // hi when bound to class instance (this.message will exist)
        // 'undefined' otherwise.
        console.log(this.message || "undefined");
    }
});

document.id(new foo()).inject(document.body);

the mouseenter here will be unbound where this will refer to the default scope (i.e the element that triggered the event - the a href). when bound, you can get the element via event.target instead - the event object is always passed on to the function as a parameter.

btw, this is a slightly less familiar use of class and element relation but it serves my purposes here to illustrate binding in the context of classes.


assig the function to a variable and use the same reference to add and remove the event. if you use an anonymous function you will get to different references

var test = function(){ alert('test: ' + this.id); } 
$('element').addEvent('click', test);

...
$('element').removeEvent('click', test);


addEvent : Attaches an event listener to a DOM element.

Example -

$('myElement').addEvent('click', function(){
    alert('clicked!');
});

removeEvent : Works as Element.addEvent, but instead removes the specified event listener.

Example -

var destroy = function(){ alert('Boom: ' + this.id); } // this refers to the Element.
$('myElement').addEvent('click', destroy);

//later...
$('myElement').removeEvent('click', destroy);

This means when you add an event with a eventhandler not an anonymous function if you than remove the event than it will be removed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜