使用Webpack后内联HTML调用filterByTypes函数返回undefined问题
问题解决:按钮onclick绑定函数后控制台输出undefined
将filterByTypes函数绑定到按钮的onclick事件后,控制台输出undefined,该功能在使用Webpack前可正常运行,怀疑是语法问题。相关原代码如下:
function filterByTypes(type) { console.log(type) getBookmarks(type) const buttons = document.querySelectorAll('.button') for (let i = 0; i < buttons.length; i++) { if (buttons[i].dataset.id === type) { buttons[i].classList.add('highlight') } else { buttons[i].classList.remove('highlight') } } } export function generateOptionsAndFilters() { for (let i = 0; i < types?.length; i++) { sourceType.innerHTML += `<option value=${types[i].value}>${types[i].selectName}</option>` filterStrip.innerHTML += `<button onclick="${filterByTypes(`${types[i].value}`)}" class="button" data-id=${types[i].value}>${types[i].selectName}</button>` } }
问题原因
核心错误在模板字符串的onclick赋值逻辑:
${filterByTypes(${types[i].value})}是直接执行函数,而非给onclick绑定函数调用语句。由于filterByTypes没有返回值,默认返回undefined,最终生成的按钮HTML会是onclick="undefined",点击时自然输出undefined。- 加上Webpack会将代码封装到模块作用域,即使语法正确,内联
onclick也无法访问模块内的filterByTypes函数,这也是Webpack后功能失效的额外原因。
解决方案
方案1:修正内联onclick的语法
把模板字符串里的onclick值改为函数调用的字符串,而非执行函数的结果:
export function generateOptionsAndFilters() { for (let i = 0; i < types?.length; i++) { sourceType.innerHTML += `<option value=${types[i].value}>${types[i].selectName}</option>` // 改为字符串形式的函数调用,而非直接执行函数 filterStrip.innerHTML += `<button onclick="filterByTypes('${types[i].value}')" class="button" data-id=${types[i].value}>${types[i].selectName}</button>` } }
注意:需要确保filterByTypes挂载到全局作用域(比如window.filterByTypes = filterByTypes),否则Webpack打包后内联事件依然找不到该函数。
方案2:使用事件监听(推荐)
放弃内联onclick,用addEventListener绑定事件,避免全局作用域依赖,更符合现代JS开发规范:
function filterByTypes(type) { console.log(type) getBookmarks(type) const buttons = document.querySelectorAll('.button') for (let i = 0; i < buttons.length; i++) { if (buttons[i].dataset.id === type) { buttons[i].classList.add('highlight') } else { buttons[i].classList.remove('highlight') } } } export function generateOptionsAndFilters() { for (let i = 0; i < types?.length; i++) { // 生成option元素 const option = document.createElement('option'); option.value = types[i].value; option.textContent = types[i].selectName; sourceType.appendChild(option); // 生成按钮元素 const button = document.createElement('button'); button.className = 'button'; button.dataset.id = types[i].value; button.textContent = types[i].selectName; // 绑定点击事件 button.addEventListener('click', () => { filterByTypes(types[i].value); }); filterStrip.appendChild(button); } }
这种方式不需要依赖全局作用域,Webpack打包后能正常运行,代码也更易维护和调试。
内容的提问来源于stack exchange,提问作者NZMAI
相关产品推荐
相关产品推荐

