我正在使用mootools并在弹出菜单上工作:
document.getElement('.cart a').toggle(
function() {
this.getParent('div').removeClass('open');
this.getNext('.cart_contents').hide();
},
function() {
this.getParent('div').addClass('open');
this.getNext('.cart_contents').show();
})
);
切换功能实现:
Element.implement({
toggle: function(fn1,fn2){
this.store('toggled',false);
return this.addEvent('click',function(event){
event.stop();
if(this.retrieve('toggled')){
fn1.call(this);
}else{
fn2.call(this);
}
this.store('toggled',!(this.retrieve('toggled')));
});
}
});
外部点击功能:
Element.Events.outerClick = {
base : 'click',
condition : function(event){
event.stopPropagation();
return false;
},
onAdd : function(fn){
this.getDocument().addEvent('click', fn);
},
onRemove : function(fn){
this.getDocument().removeEvent('click', fn);
}
};
我想添加outerclick事件来关闭弹出菜单:
document.getElement('.cart a').toggle(
function() {
this.getParent('div').removeClass('open');
this.getNext('.cart_contents').hide();
},
function() {
this.getParent('div').addClass('open');
this.getNext('.cart_contents').show();
}).addEvent('outerClick',function() {
// Error: Wrong code below
// Uncaught TypeError: Object #<HTMLDocument> has no method 'getParent'
this.getParent('div').removeClass('open');
this.getNext('.cart_contents').hide();
});
错误:未捕获TypeError:对象#没有方法&#39; getParent&#39; 感谢。
答案 0 :(得分:3)
这是与Darren outerClick
实施有关的问题(或缺陷)。这不是一个错误 - 它是为了尽可能快地工作而构建的。你只需要理解它将实际事件绑定到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);
}
};
因此函数将与上下文this === document
一起运行。
修复它的一种方法是将回调专门绑定到元素。问题是,删除它将无效,因为.bind
将返回一个唯一的新功能,它将再次与同一功能不匹配。
(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/ - 这将暂时起作用 - 取决于你是否有一个析构函数来删除它。
另一种方法是在您添加事件时:
var el = document.getElement('.cart a');
el.addEvent('outerClick', function(){ el.getParent(); // etc });
// or bind it
el.addEvent('outerClick', function(){ this.getParent(); }.bind(el));
如果您保存参考
,则可以删除它var el = document.getElement('.cart a'),
bound = function(){
this.getParent('div');
}.bind(el);
el.addEvent('outerClick', bound);
// later
el.removeEvent('outerClick', bound);
就是这样。另一个outerClick
在这里:https://github.com/yearofmoo/MooTools-Event.outerClick/blob/master/Source/Event.outerClick.js - 没试过,但看起来它试图通过将范围更改为元素并保持对已记忆函数的引用来做正确的事情 - 尽管多个事件可能会导致问题,需要事件ID来识别要删除的精确函数。此外,它看起来很重 - 考虑到事件是在文档上,你不希望在每次点击上做太多逻辑。