JavaScript函数未返回按钮文本值反而输出undefined求助
问题解答
能不能从事件监听器中返回值?
不能。原因有两点:
- 事件监听是异步触发的:
choosenOrder函数执行时,点击事件还没发生,函数会直接执行完并返回默认的undefined,根本等不到点击动作触发。 - 监听函数的返回值没有接收方:
addEventListener不会处理监听函数的返回值,哪怕你在监听里return了值,也没有任何机制能把这个值传递到外部的choosenOrder函数中。
你的代码里choosenOrder本身没有任何return语句,所以调用它自然会输出undefined,哪怕监听函数里写了return mychoice也没用。
替代方案
方案1:使用回调函数
把处理点击结果的逻辑作为参数传入choosenOrder,当按钮被点击时调用这个回调函数传递值。
let btns = document.querySelectorAll("button"); function choosenOrder(chices1, callback) { let btnsPair = [chices1[0], chices1[1]]; btnsPair.forEach((choice) => { choice.addEventListener("click", (c1) => { let mychoice = c1.target.textContent; callback(mychoice); // 调用回调传递结果 }) }) } // 使用时传入处理逻辑 choosenOrder(btns, (result) => { console.log("你点击了:", result); });
方案2:使用Promise包装点击事件
如果需要在异步流程中等待点击结果,可以把按钮点击包装成Promise,多个按钮的话可以用Promise.race(取首个点击结果)或者Promise.all(等待所有点击)。
let btns = document.querySelectorAll("button"); function choosenOrder(chices1) { return new Promise((resolve) => { let btnsPair = [chices1[0], chices1[1]]; // 给每个按钮绑定点击事件,触发后resolve并移除监听 const handleClick = (c1) => { let mychoice = c1.target.textContent; resolve(mychoice); btnsPair.forEach(btn => btn.removeEventListener("click", handleClick)); }; btnsPair.forEach((choice) => { choice.addEventListener("click", handleClick); }) }) } // 使用async/await获取结果 async function getChoice() { const result = await choosenOrder(btns); console.log("你点击了:", result); } getChoice();
方案3:使用自定义事件
在按钮点击时派发一个自定义事件,在其他地方监听这个事件来获取值,适合需要在多个地方接收点击结果的场景。
let btns = document.querySelectorAll("button"); function choosenOrder(chices1) { let btnsPair = [chices1[0], chices1[1]]; btnsPair.forEach((choice) => { choice.addEventListener("click", (c1) => { let mychoice = c1.target.textContent; // 派发自定义事件 document.dispatchEvent(new CustomEvent("buttonChoice", { detail: mychoice })); }) }) } choosenOrder(btns); // 监听自定义事件获取结果 document.addEventListener("buttonChoice", (e) => { console.log("你点击了:", e.detail); });
方案4:使用全局变量(不推荐)
把点击结果存到全局变量中,后续读取这个变量。但这种方式容易造成变量污染,且无法精准控制时机,仅适合简单场景。
let btns = document.querySelectorAll("button"); let clickResult = undefined; // 全局变量 function choosenOrder(chices1) { let btnsPair = [chices1[0], chices1[1]]; btnsPair.forEach((choice) => { choice.addEventListener("click", (c1) => { clickResult = c1.target.textContent; }) }) } choosenOrder(btns); // 后续可以通过clickResult获取值,但要注意点击事件是否已触发
内容的提问来源于stack exchange,提问作者WeweroWawora Wooo
相关产品推荐
相关产品推荐

