如何在DOM元素dataset存储的调用方法中正确传入this作为参数?
问题根因
你当前实现无法正确传参的核心原因是:通过new Function生成的函数默认执行上下文为全局window对象,直接调用FN()时,代码中写入的this指向的是全局对象而非触发点击事件的DOM元素。
修复方案一:最小改动兼容原有写法
仅修改事件监听的执行逻辑,通过call将目标元素绑定为待执行函数的上下文,同时增加冒泡兼容逻辑,避免元素内部有嵌套子节点时点击失效:
document.addEventListener('click', function(event) { let el = event.target; // 向上查找最近带data-todo属性的父元素,兼容元素内嵌套子节点场景 while (el && !el.hasAttribute('data-todo')) { el = el.parentElement; } if (el) { let FN = new Function(el.dataset.todo); // 将当前元素绑定为函数执行的this上下文 FN.call(el); } }); function toggleDisable(el) { console.log(el.tagName); el.classList.add('disabled'); }
原有HTML代码无需改动即可正常运行。
修复方案二:更安全的实现(推荐)
直接执行new Function存在XSS注入风险,建议拆分方法名和参数,显式调用全局方法:
修改后的HTML代码
<div class="wrapper"> <button type="button" data-todo="toggleDisable">Disable me</button> </div>
修改后的JS代码
document.addEventListener('click', function(event) { let el = event.target; while (el && !el.hasAttribute('data-todo')) { el = el.parentElement; } if (el) { const methodName = el.dataset.todo; // 校验方法存在再调用,避免报错 if (typeof window[methodName] === 'function') { window[methodName](el); } } }); function toggleDisable(el) { console.log(el.tagName); el.classList.add('disabled'); }
内容的提问来源于stack exchange,提问作者meYnot
相关产品推荐
相关产品推荐

