添加EventListener时出现Uncaught ReferenceError问题排查
区块拖拽功能实现中的监听器引用错误问题
我尝试用类独立实现区块拖拽功能,添加EventListener时出现异常。点击label元素后控制台抛出错误:
Uncaught ReferenceError: listener is not defined
at HTMLDocument.(main.js:31:63)
(anonymous) @ main.js:31
如果在类外部对已存在DOM元素执行相同逻辑代码能正常运行;改成具名函数形式后拖拽功能生效,但移除监听器时还是报同样的错。
原实现代码
class Form { constructor() { //pass } DOMGenerator(elemClass) { const element = document.createElement('div'); element.classList.add(elemClass); return element; } Draw() { const form = this.DOMGenerator('window'), label = this.DOMGenerator('window_label'), controls = this.DOMGenerator('window_controls'), close = this.DOMGenerator('close'), minimize = this.DOMGenerator('minimize'), maximize = this.DOMGenerator('maximize') label.addEventListener('mousedown', event => { const offsetX = event.offsetX; const offsetY = event.offsetY; document.addEventListener('mousemove', listener = event => { let pageX = event.pageX; let pageY = event.pageY; form.style.left = `${pageX - offsetX}px`; form.style.top = `${pageY - offsetY}px`; }) document.addEventListener('mouseup', () => { document.removeEventListener('mousemove', listener, false); }) }) controls.append(close, minimize, maximize); label.append(controls); form.append(label); document.body.append(form); } } new Form().Draw();
修改后的具名函数代码
document.addEventListener('mousemove', function listener(event) { let pageX = event.pageX; let pageY = event.pageY; form.style.left = `${pageX - offsetX}px`; form.style.top = `${pageY - offsetY}px`; })
问题原因及解决方法
错误根源
- 第一种写法中,
listener = event => {...}试图赋值给未声明的变量,类内部默认运行在严格模式下,不会自动创建全局变量,导致mouseup回调执行时找不到listener。 - 修改后的具名函数写法里,
function listener是函数表达式的内部名称,仅在函数自身范围内可见,外部的mouseup回调无法访问这个引用,因此removeEventListener无法匹配到对应的监听器。
- 第一种写法中,
正确实现方案
在mousedown回调内部提前声明拖拽处理函数,让mouseup回调能直接访问到这个函数引用:label.addEventListener('mousedown', event => { const offsetX = event.offsetX; const offsetY = event.offsetY; // 提前定义拖拽处理函数 const dragHandler = event => { let pageX = event.pageX; let pageY = event.pageY; form.style.left = `${pageX - offsetX}px`; form.style.top = `${pageY - offsetY}px`; } document.addEventListener('mousemove', dragHandler); document.addEventListener('mouseup', () => { document.removeEventListener('mousemove', dragHandler); }) })额外提示
- 确保给
form元素添加position: absolute或position: fixed样式,否则left和top属性不会生效。
- 确保给
内容的提问来源于stack exchange,提问作者ExisterPro
相关产品推荐
相关产品推荐

