繁体   English   中英

无法删除 windows 对象的事件侦听器

[英]Can't remove event listener for windows object

我在尝试删除事件侦听器时遇到了很多麻烦。

我创建了一个非常依赖 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. 您必须向removeEventListener传递与传递给addEventListener相同的函数。 (同样,您必须向detachEvent传递与使用 Microsoft 专有的东西传递给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 )是一个匿名箭头函数,您不会在任何地方保存,但传递removeEventListener的函数是调用scrollRoute[func]()

您需要保留对传递addEvent的函数的引用,然后将相同的函数传递给一个函数,该函数将撤消addEvent所做的事情(可能是removeEvent ?)。 或者,再次抛弃所有这些,不支持 IE8,直接使用addEventListener

所以例如:

var scrollHandler = function(options) {
    var func = options.func.name;
    var funcOptions = options.func.options;
    var elem = options.elem;
    var flag = options.flag;
    var handler = () => {
        scrollRoute[func](elem, funcOptions);
    };

    this.events = () => {
        elem.addEventListener('scroll', handler, flag);
    };
    this.clear = () => {
        elem.removeEventListener('scroll', handler, flag);
    };
};

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

或者使用 ES2015 的更多特性(因为你已经在使用箭头函数了):

var scrollHandler = function(options) {
    const {elem, flag, func: {name, options}} = options;
    const handler = () => {
        scrollRoute[name](elem, options);
    };

    this.events = () => {
        elem.addEventListener('scroll', handler, flag);
    };
    this.clear = () => {
        elem.removeEventListener('scroll', handler, flag);
    };
};

暂无
暂无

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

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