简体   繁体   English

mootools | 打开/关闭弹出菜单和外部单击事件

[英]mootools | Open/close popup menu and outer click event

I'm using mootools and working on popup menu: 我正在使用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();
  })
);

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: 我想添加externalclick事件以关闭我的弹出菜单:

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. 错误:未被捕获的TypeError:对象#没有方法'getParent'谢谢。

This is a problem (or a deficiency) to do with the outerClick implementation by Darren. 这是达伦(Darren)实现的outerClick实现的问题 (或不足)。 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 . 您只需要了解将实际事件绑定到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 . 因此,这些函数将在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. 问题是,将其删除将不起作用,因为.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/ - this will work for now - depends if you have a destructor that removes it. http://jsfiddle.net/dimitar/UZRx5/-现在可以使用-取决于是否有析构函数将其删除。

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. 另一种替代的outerClick在这里: https : //github.com/yearofmoo/MooTools-Event.outerClick/blob/master/Source/Event.outerClick.js-尚未尝试过,但看起来它试图通过更改范围来做正确的事情元素并保留所记忆的功能的引用-尽管可能会发生多个事件,但仍需要事件ID来标识要删除的确切功能。 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. 同样,它看起来也很沉重-考虑到事件已记录在案,您不希望对每次冒泡的点击都不要做太多的逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM