编程技术网

关注微信公众号,定时推送前沿、专业、深度的编程技术资料。

 找回密码
 立即注册

QQ登录

只需一步,快速开始

极客时间

无法删除Windows对象的事件侦听器:Can't remove event listener for windows object

webcompat-bot 集合 2022-5-11 10:31 8人围观

腾讯云服务器
无法删除Windows对象的事件侦听器的处理方法

尝试删除事件侦听器时遇到很多麻烦.

I am having a lot of trouble trying to remove an event listener.

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

I have created a website that relies on JavaScript quite heavily. When you navigate on the website it is basically loading in elements dynamically without a page refresh with template literals.

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

I have to sometimes load in content and add infinite scroll but also be able to remove that event again.

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

This is the code I use to handle scroll events:

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); } } 

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

I am using this function to set events

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]; } } 

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

I am calling this code from whatever code when I need to set the infinite scroll event

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

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

I am calling this code from whatever code when I need to remove the infinite scroll event but without any luck

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

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

How do I successfully remove the event listener? I can't just name the instances, that will be so messy in the long run when setting and removing the scroll events from various different places.

问题解答

两个问题:

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

  1. You have to pass the same function to removeEventListener as you passed to addEventListener. (Similarly, you have to pass the same function to detachEvent as you passed to attachEvent using Microsoft's proprietary stuff — but unless you really have to support IE8 and earlier, you can ditch all that.) Your code isn't doing that.

尝试删除处理程序时,您正在调用 scrollRoute [func]()并将其返回值传递到 removeEventListener .据我所知,这是将 undefined 传递给 removeEventListener ,这不会做任何有用的事情.

When trying to remove the handler, you're calling scrollRoute[func]() and passing its return value into removeEventListener. As far as I can tell, that's passing undefined into removeEventListener, which won't do anything useful.

这是我上面所指的代码:

Here's the code I'm referring to above:

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]()的结果.

Notice that the function you're passing addEvent (which will pass it to addEventListener) is an anonymous arrow function you don't save anywhere, but the function you're passing removeEventListener is the result of calling scrollRoute[func]().

您需要保留对传递 addEvent 的函数的引用,然后将该 same 函数传递给将撤消 addEvent 的函数的函数.code>做过(也许 removeEvent ?).或者再次放弃所有内容,不支持IE8,直接使用 addEventListener .

You'll need to keep a reference to the function you pass addEvent and then pass that same function to a function that will undo what addEvent did (removeEvent, perhaps?). Or, again, ditch all that, don't support IE8, and use addEventListener directly.

例如:

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的更多功能(因为您已经在使用箭头功能):

Or using more features of ES2015 (since you're using arrow functions already):

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); }; }; 

这篇关于无法删除Windows对象的事件侦听器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程技术网(www.editcode.net)!

腾讯云服务器 阿里云服务器
关注微信
^