Mootools | Open/close Popup Menu And Outer Click Event
Solution 1:
This is a problem (or a deficiency) to do with the outerClick
implementation by Darren. It's not a bug - it's built to work as fast as possible. you just need to understand what it does when it binds the actual event to document
.
Element.Events.outerClick = {
base : 'click',
condition : function(event){
event.stopPropagation();
return false;
},
onAdd : function(fn){
// the event actually gets added to document!
// hence scope in fn will be document as delegator.
this.getDocument().addEvent('click', fn);
},
onRemove : function(fn){
this.getDocument().removeEvent('click', fn);
}
};
So the functions will run with context this === document
.
One way to fix it is to bind the callback specifically to the element. Problem is, removing it won't work as .bind
will return a unique new function that won't match the same function again.
(function(){
var Element = this.Element,
Elements = this.Elements;
[Element, Elements].invoke('implement', {
toggle: function(){
var args = Array.prototype.slice.call(arguments),
count = args.length-1,
// start at 0
index = 0;
return this.addEvent('click', function(){
var fn = args[index];
typeof fn === 'function' && fn.apply(this, arguments);
// loop args.
index = count > index ? index+1 : 0;
});
}
});
Element.Events.outerClick = {
base : 'click',
condition : function(event){
event.stopPropagation();
return false;
},
onAdd : function(fn){
this.getDocument().addEvent('click', fn.bind(this));
},
onRemove : function(fn){
// WARNING: fn.bind(this) !== fn.bind(this) so the following
// will not work. you need to keep track of bound fns or
// do it upstream before you add the event.
this.getDocument().removeEvent('click', fn.bind(this));
}
};
}());
document.id('myp').toggle(
function(e){
console.log(e); // event.
this.set('html', 'new text');
},
function(){
console.log(this); // element
this.set('html', 'old text');
},
function(){
this.set("html", "function 3!");
}
).addEvent('outerClick', function(e){
console.log(this, e);
});
http://jsfiddle.net/dimitar/UZRx5/ - this will work for now - depends if you have a destructor that removes it.
Another approach is when you add the event to do so:
var el = document.getElement('.cart a');
el.addEvent('outerClick', function(){ el.getParent(); // etc });
// or bind it
el.addEvent('outerClick', function(){ this.getParent(); }.bind(el));
it can then be removes if you save a ref
var el = document.getElement('.cart a'),
bound = function(){
this.getParent('div');
}.bind(el);
el.addEvent('outerClick', bound);
// later
el.removeEvent('outerClick', bound);
that's about it. an alternative outerClick
is here: https://github.com/yearofmoo/MooTools-Event.outerClick/blob/master/Source/Event.outerClick.js - not tried it but looks like it tries to do the right thing by changing scope to element and keeping a reference of the memoized functions - though multiple events will likely cause an issue, needs event ids to identify the precise function to remove. Also, it looks quite heavy - considering the event is on document, you want to NOT do too much logic on each click that bubbles to that.
Post a Comment for "Mootools | Open/close Popup Menu And Outer Click Event"