我正在使用 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();
});
错误:未捕获类型错误:对象#没有方法“getParent” 谢谢。
最佳答案
这是一个与 Darren 的 outerClick
实现有关的问题(或缺陷)。这不是一个错误——它是为了尽可能快地工作而构建的。您只需要了解它将实际事件绑定(bind)到 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)到元素。问题是,删除它不起作用,因为 .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 来识别要删除的精确函数。另外,它看起来相当沉重 - 考虑到该事件是在文档中的,您不想在每次点击时执行太多逻辑。
关于javascript - 穆工具 |打开/关闭弹出菜单和外部单击事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22449501/