无法删除Windows对象的事件监听器

时间:2019-12-22 12:30:48

标签: javascript event-listener removeeventlistener

尝试删除事件监听器时遇到很多麻烦。

我创建了一个非常依赖JavaScript的网站。当您在网站上导航时,它基本上是在动态加载元素,而无需使用模板文字刷新页面。

有时我必须加载内容并添加无限滚动,而且还必须再次删除该事件。

这是我用来处理滚动事件的代码:

var start  = 30;
var active = true;

function yHandler(elem)
{

    var oHeight = selectElems('content_main', 'i').offsetHeight;
    var yOffset = window.pageYOffset;
    var hLimit  = yOffset + window.innerHeight;

    if (hLimit >= oHeight - 500 && active === true)
    {

        active = false;
        new requestContent({
            page: GET.page,
            type: returnContentType(GET.page),
            scroll: true,
            start: start
        }, (results) => {
            if(results){
                setTimeout(()=>{
                    active = true;
                    start  = start + 30;;
                }, 400);
                new ContentActive();
            }
        });
    }
}

var scrollRoute = 
    {

    contentScroll: () =>{
        yHandler();
    }
};

var scrollHandler = function(options)
{

    var func = options.func.name;
    var funcOptions = options.func.options;
    var elem = options.elem;
    var flag = options.flag;

    this.events = () => {
        addEvent(elem, 'scroll', ()=>{
            scrollRoute[func](elem, funcOptions);
        }, flag);
    }
    this.clear = () => {
        elem.removeEventListener('scroll', scrollRoute[func](), flag);
    }
}

我正在使用此功能设置事件

function addEvent(obj, type, fn, flag = false) {
    if (obj.addEventListener) {
        obj.addEventListener(type, fn, flag);
    } else if (obj.attachEvent) {
        obj["e" + type + fn] = fn;
        obj[type + fn] = function () {
            obj["e" + type + fn](window.event);
        };
        obj.attachEvent("on" + type, obj[type + fn]);
    } else {
        obj["on" + type] = obj["e" + type + fn];
    }
}

当我需要设置无限滚动事件时,我会从任何代码中调用此代码

new scrollHandler({
    func: {
        'name':'contentScroll',
    },
    elem: window,
    flag: true,
}).events();

当我需要删除无限滚动事件但没有任何运气的时候,我会从任何代码中调用此代码

new scrollHandler({
    func: {
        'name':'contentScroll',
    },
    elem: window,
    flag: true,
}).clear();

如何成功删除事件监听器?我不能只是命名实例,从长远来看,在各个不同位置设置和删除滚动事件时,这样会很混乱。

1 个答案:

答案 0 :(得分:3)

两个问题:

  1. 您必须将传递给removeEventListener same 函数传递给addEventListener。 (类似地,您必须使用Microsoft专有的东西传递给detachEvent的函数传递给attachEvent-但是除非您真的必须支持IE8和更早版本,否则您可以放弃所有这些。)没有这样做。

  2. 尝试删除处理程序时,您正在调用 scrollRoute[func](),并将其返回值传递到removeEventListener。据我所知,这是将undefined传递到removeEventListener中,这将无济于事。

这是我上面所指的代码:

this.events = () => {
    addEvent(elem, 'scroll', ()=>{               // *** Arrow function you don't
        scrollRoute[func](elem, funcOptions);    // *** save anywhere
    }, flag);                                    // ***
}
this.clear = () => {
    elem.removeEventListener('scroll', scrollRoute[func](), flag);
// Calling rather than passing func −−−^^^^^^^^^^^^^^^^^^^
}

请注意,您正在传递的函数addEvent(它将传递给addEventListener)是一个匿名箭头函数,您不会在任何地方保存,但是您正在传递的函数{{1 }}是呼叫 removeEventListener的结果。

您需要保留对通过scrollRoute[func]()传递的函数的引用,然后将该相同函数传递给将撤消addEvent所做的操作的函数({{ 1}},也许?)。或者再次放弃所有内容,不支持IE8,直接使用addEvent

例如:

removeEvent

(注意,我添加了一些缺少的分号,因为您似乎在其他地方使用了它们,并且花括号的位置保持一致。)

或使用ES2015的更多功能(因为您已经在使用箭头功能):

addEventListener