mootools |打开/关闭弹出菜单和外部点击事件 [英] mootools | Open/close popup menu and outer click event
问题描述
document.getElement('。cart a')。 (
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();
返回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(){
//错误:代码低于
//未捕获TypeError:对象#< HTMLDocument>没有方法'getParent'
this.getParent('div')。removeClass('open');
this.getNext('。cart_contents')。hide();
});
错误:未捕获TypeError:对象#没有方法'getParent'
谢谢。 p>
这是一个问题(或缺陷)与 outerClick达伦执行
这不是一个错误 - 它的构建尽可能快地工作。您只需要了解它将实际事件绑定到文档
时的操作。
Element.Events.outerClick = {
base:'click',
condition:function(event){
event.stopPropagation();
返回false;
},
onAdd:function(fn){
//事件实际上被添加到文档!
//因此fn中的范围将作为委托者的文档。
this.getDocument()。addEvent('click',fn);
},
onRemove:function(fn){
this.getDocument()。removeEvent('click',fn);
}
};
所以函数将使用上下文这个===文档
。
一种解决方法是将回调绑定到该元素。问题是,删除它将无法正常工作,因为 .bind
将返回一个独特的新功能,不能再匹配相同的功能。
(function(){
var Element = this.Element,
Elements = this.Elements;
[元素,元素] .invoke('implement',{
toggle:function(){
var args = Array.prototype.slice.call(arguments),
count = args.length- 1,
//从0开始
index = 0;
返回this.addEvent('click',function(){
var fn = args [index ];
typeof fn ==='function'&& fn.apply(this,arguments);
//循环args
index = count> index?index + 1 :$;
});
}
});
Element.Events.outerClick = {
base:'click',
条件:function(event){
event.stopPropagation();
返回false;
},
onAdd:function(fn){
this.getDocument()。addEvent('click',fn.bind(this));
},
onRemove:function(fn){
//警告:fn.bind(this)!== fn.bind(this)所以以下
//将不行。您需要跟踪绑定的fns或
//在添加事件之前上游。
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); //元素
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});
//或绑定
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来标识要删除的精确函数。此外,它看起来相当沉重 - 考虑到事件在文档上,您不想对每个点击发生过多的逻辑。
I'm using mootools and working on popup menu:
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();
})
);
The toggle function implementation:
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')));
});
}
});
The outer click function:
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);
}
};
I would like to add outerclick event to close my popup menu:
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();
});
Error: Uncaught TypeError: Object # has no method 'getParent' Thanks.
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.
这篇关于mootools |打开/关闭弹出菜单和外部点击事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!