1

我在删除滑块元素的事件处理程序时遇到问题

如果我不为处理程序使用代理,“this”将指向 dom 元素

如何删除处理程序?

相关代码:

var slider = (function (slider) {
    
    
var Sliderhandle = function(handle){
    EvtTarget.call(this);
    
    this.events = { 
        start: ['touchstart', 'mousedown'],
        move: ['touchmove', 'mousemove'],
        end: ['touchend', 'touchcancel', 'mouseup']
    };
    
    this.options = {};
    this.element = $$('div.ui-slider');
    // set context for event handlers
    this.start = this.start.bind(this);
    this.move = this.move.bind(this);
    this.end = this.end.bind(this);
    
    this.proxy = function(func){
        var that = this;
        return(function(){
         return func.apply(that,arguments); 
        });
    }
    
    Object.defineProperty(this, "__el",{
        value:handle
    });
    
};


    Sliderhandle.prototype = Object.create(EvtTarget.prototype,{
        init : {
            value:function(config){
                
                

                this.container = $$('div.ui-slider');                                                                      
                this.track = this.container.getElementsByClassName('ui-slider-track')[0];
                
                this.value = (config && config.value) || 1;
                this.min = (config && config.min) || 1;
                this.max = (config && config.value) || 1000;
                this.change = (config && config.change) || null; // callback
                
                this.addEvents("start");
                this.setValue(this.value);
                
            },
            enumerable:true
        },
        
        addEvents : {
            value:function(name){
                var list = this.events[name], 
                    handler = this[name],
                    all;
                handler = this.proxy(handler);
                for (all in list){
                  this.container.addEventListener(list[all], handler, false);
                }       
            },
            enumerable:true
        },
        removeEvents:{
            value:function(name){
                var list = this.events[name], 
                    handler = this[name],
                    all;
                //handler = this.proxy(handler);   
                for (all in list){
                  this.container.removeEventListener(list[all], handler, false);
                }
            },
            enumerable:true
        },
4

1 回答 1

1

问题是因为没有与handler传递给removeEventListener. this.proxy()为每个调用生成新函数。即使您使用相同的参数调用它,它也会返回完全不同的函数对象,尽管返回的函数在语义上将执行相同的工作。

您应该在添加时存储代理功能,然后在删除时使用该代理功能,如下所示:

var Sliderhandle = function(handle){
    // ....
    this.proxyHandler = {};
}

// ....

addEvents : {
    value: function(name){
        var list = this.events[name], 
            handler = this[name],
            all;
        this.proxyHandler[name] = handler = this.proxy(handler);
        for (all in list){
            this.container.addEventListener(list[all], handler, false);
        }       
    },
    enumerable:true
},
removeEvents:{
    value:function(name){
        var list = this.events[name], 
            handler = this.proxyHandler[name],
            all;  
        for (all in list){
            this.container.removeEventListener(list[all], handler, false);
        }
        delete this.proxyHandler[name];
    },
    enumerable:true
},
于 2013-08-02T08:20:37.730 回答