如何在闭包范围内传递事件处理程序

时间:2015-04-16 14:22:28

标签: javascript javascript-events event-handling scope

我正在尝试向我的范围添加事件处理程序。函数addEvent工作正常。但是如果我将一个函数传递给这样的处理程序:

this.addEvent(window, "resize", self.resizeAd(this));

该函数不会传递给事件(The eventHandle is undefinded),我不知道为什么。

这是我的代码:

(function(window, document, undefined) {
    'use strict';
    var adTech = window.adTech = {
        get: function() {
            return _instance;
        },
        //Main entry point.
        init: function(options) {
            return _instance || new ADTECH(options);
        }
    };
    var ADTECH = function(options) {
        var defaultOptions = {
            adID : '5202402',
            hiddenClassName : 'hidden'
        };
        this.options = this.extend(options, defaultOptions);
        this.makeAd();
        _instance = this;
        return _instance;
    }

    ADTECH.prototype = {
        extend: function(source, target) {
            if (source == null) { return target; }
            for (var k in source) {
                if(source[k] != null && target[k] !== source[k]) {
                    target[k] = source[k];
                }
            }
            return target;
        },
        log: function(msg){
            if(window.console){
                console.log(msg);
            }
        },
        debounce:  function(func, wait, immediate) {
            var timeout;
            return function() {
                var context = this, args = arguments;
                var later = function() {
                    timeout = null;
                    if (!immediate) func.apply(context, args);
                };
                var callNow = immediate && !timeout;
                clearTimeout(timeout);
                timeout = setTimeout(later, wait);
                if (callNow) func.apply(context, args);
            };
        },
        addEvent: function (elem, type, eventHandle) {
            console.log("adEvent is undefined: ",eventHandle);
            if (elem == null || typeof(elem) == 'undefined') return;
            if (elem.addEventListener) {
                elem.addEventListener(type, eventHandle, false);
            } else if (elem.attachEvent) {
                elem.attachEvent("on" + type, eventHandle);
            } else {
                elem["on" + type] = eventHandle;
            }
        },
        // Function to resize div ad to take the full space we need / get
        resizeAd : function(this){
            this.log("resizeAd done.");
            var ad = document.getElementById(this.options.adID);
            this.log(ad);
            // do not work
            // this.debounce(function() {
            // console.log("tat:");
            // }, 250)
        },
        // insert ad
        makeAd: function () {
            this.addEvent(window, "resize", this.resizeAd(this));
            var self = this;
            //also do not work
            this.addEvent(window, "resize", self.resizeAd(this)); 
        }
    }
    // Singleton
    var _instance;
}(window, document));

var API = adTech.init();

1 个答案:

答案 0 :(得分:0)

修改resizeAd函数以返回函数。此外,在这种情况下也不需要将对象显式传递给方法。此外,this是保留字,不能用作参数。

// ...
resizeAd: function(invokeLater) {
    // this is explicitly set based on the calling object.
    var obj = this;
    var helper = function ()
       obj.log("resizeAd done.");
       var ad = document.getElementById(obj.options.adID);
       obj.log(ad);
       obj.debounce(function() {
           console.log("tat:");
       }, 250)
    };
    // if invokeLater is a falsey value do the resizing right away
    // if it is truthy return helper so that it can be assigned as
    // an event handler
    return invokeLater ? helper : helper();
}, 
makeAd: function () {
    this.addEvent(window, "resize", this.resizeAd(true));
}

// note that you can still call resize normally.
this.resize();

在分配事件处理程序时调用函数时出现The eventHandle is undefinded错误。

this.addEvent(window, "resize", this.resizeAd(this));

当未明确声明return时,JavaScript函数隐式返回undefined。除了在使用new调用函数的情况下,在这种情况下,隐式返回新创建的对象。