如何用原生JavaScript点击HTML中类按钮的DIV元素(Lyrics Training自动化)
自动化Lyrics Training点击DIV选项的解决方案
问题描述
我正在用JavaScript扩展自动化Lyrics Training游戏,已经通过其他代码获取到选项文本,但操作对象是HTML中的DIV元素(而非原生按钮),调用click()方法、添加role="button"属性的方案都无法触发点击。
现有尝试代码
尝试代码1
let firstChoice = document.getElementsByClassName("slot s1")[0]; let secondChoice = document.getElementsByClassName("slot s2")[0]; let thirdChoice = document.getElementsByClassName("slot s3")[0]; let fourthChoice = document.getElementsByClassName("slot s4")[0]; // 点击函数无效 for(let i = 0; i < click_order.length; i++){ let word = click_order[i]; if(firstChoice.innerHTML === word){ firstChoice.click(); }else if(secondChoice.innerHTML === word){ secondChoice.click(); }else if(thirdChoice.innerHTML === word){ thirdChoice.click(); }else if(fourthChoice.innerHTML === word){ fourthChoice.click(); } }
尝试代码2
let firstChoice = document.getElementsByClassName("slot s1")[0]; let secondChoice = document.getElementsByClassName("slot s2")[0]; let thirdChoice = document.getElementsByClassName("slot s3")[0]; let fourthChoice = document.getElementsByClassName("slot s4")[0]; // 给所有选项添加button角色 firstChoice.setAttribute("role", "button"); secondChoice.setAttribute("role", "button"); thirdChoice.setAttribute("role", "button"); fourthChoice.setAttribute("role", "button"); for(let i = 0; i < click_order.length; i++){ let word = click_order[i]; if(firstChoice.innerHTML === word){ firstChoice.click(); }else if(secondChoice.innerHTML === word){ secondChoice.click(); }else if(thirdChoice.innerHTML === word){ thirdChoice.click(); }else if(fourthChoice.innerHTML === word){ fourthChoice.click(); } }
目标DIV结构
<div class="slot s1" style=""><b style="opacity: 1; transform: matrix(1, 0, 0, 1, 0, 0);">Hope</b><ol></ol></div>
可行解决方案
1. 修正文本匹配逻辑
原代码的核心问题之一是文本匹配错误:你用innerHTML判断,但目标文本实际在<b>标签内,innerHTML包含标签结构(比如"<b>Hope</b><ol></ol>"),和你拿到的纯文本word无法匹配。
修正匹配逻辑,改用textContent获取纯文本:
// 封装获取选项文本的函数 function getSlotText(slotElement) { return slotElement.querySelector('b').textContent.trim(); } let slots = [ document.querySelector(".slot.s1"), document.querySelector(".slot.s2"), document.querySelector(".slot.s3"), document.querySelector(".slot.s4") ]; for(let word of click_order) { const targetSlot = slots.find(slot => getSlotText(slot) === word); if(targetSlot) { // 先尝试基础click,不行再用下面的模拟事件 targetSlot.click(); } }
2. 模拟真实鼠标事件
很多网站会监听mousedown、mouseup这类底层事件,而非单纯的click()方法。可以手动创建并触发完整的鼠标事件链:
function simulateClick(element) { // 创建并触发mousedown事件 const mousedownEvent = new MouseEvent('mousedown', { bubbles: true, cancelable: true, view: window }); element.dispatchEvent(mousedownEvent); // 创建并触发mouseup事件 const mouseupEvent = new MouseEvent('mouseup', { bubbles: true, cancelable: true, view: window }); element.dispatchEvent(mouseupEvent); // 创建并触发click事件 const clickEvent = new MouseEvent('click', { bubbles: true, cancelable: true, view: window }); element.dispatchEvent(clickEvent); } // 使用修正后的匹配逻辑,找到目标slot后调用simulateClick for(let word of click_order) { const targetSlot = slots.find(slot => getSlotText(slot) === word); if(targetSlot) { simulateClick(targetSlot); // 可添加延迟模拟人类点击间隔 await new Promise(resolve => setTimeout(resolve, 200)); } }
3. 直接调用绑定的事件处理函数
如果上面的方法都无效,可以查看元素绑定的事件监听器:
- 打开浏览器开发者工具(F12),选中目标DIV
- 切换到「Event Listeners」标签,找到
click或mousedown对应的处理函数 - 直接调用该函数(注意上下文绑定)
示例(假设找到的处理函数是handleSlotClick):
// 注意:实际函数名需要从开发者工具中获取 targetSlot.handleSlotClick();
内容的提问来源于stack exchange,提问作者Heeny Leeny
相关产品推荐
相关产品推荐

