Android设备keydown事件失效,表格着色功能异常求助
Android设备扫描器无法触发keydown事件的问题
问题背景
桌面端可正常运行:扫描器输入触发keydown事件,收集非Enter键的输入内容,检测到Enter键时调用TableIt函数匹配表格单元格内容,为对应行设置背景色。
但在Android设备上使用同款扫描器时,keydown事件无法正常触发,导致表格无法着色。尝试改用input事件也未解决,且无法在该Android设备上进行全面调试。
原始代码
JavaScript代码
// document.getElementById("title").setAttribute("innerHTML", "") let text = "" document.addEventListener('keydown', (event) => { if (event.key != 'Enter') { var name = event.key; var code = event.code; text += event.key } }, false); document.addEventListener('keydown', (event) => { if (event.key === 'Enter') { console.log(text) //myFunction(1); TableIt(text); text = "" } }) function myFunction(string) { document.getElementById(string).setAttribute("bgcolor","#dee") } function TableIt(text) { var table = document.getElementById("VareTable"); for (var i = 0, row; row = table.rows[i]; i++) { //rows would be accessed using the "row" variable assigned in the for loop for (var j = 0, col; col = row.cells[j]; j++) { if (col.innerHTML === text) { myFunction(i-1); } //columns would be accessed using the "col" variable assigned in the for loop } } }
HTML代码
@page @model WebStore.Pages.VareModel @{} <br /> <h2 id="title">@(Model.Loc.Location)</h2> <table class="table" id="VareTable"> <thead> <tr> <th>Item</th> <th>Quantity</th> <th>Description</th> <th>EanNum</th> </tr> </thead> <tbody> @foreach (var Info in Model.listItems) { <tr id="@Info.ItemID"> <td>@Info.Item</td> <td>@Info.Qty</td> <td>@Info.Description</td> <td id="@Info.ItemID ean">@Info.EAN</td> </tr> } </tbody> </table>
解决方案
移动设备对全局keydown事件的支持存在差异,且扫描器在移动设备上的输入模拟方式可能与桌面端不同。以下是针对性的修改方案:
核心思路
- 使用隐藏的输入框捕获扫描器输入:移动设备对输入框的事件支持更稳定,扫描器通常会自动将内容输入到聚焦的输入框中。
- 优先监听
input事件捕获内容,同时保留keyup作为备用方案。 - 优化内容匹配和行定位逻辑,避免依赖索引计算,提升可靠性。
修改后的代码
更新HTML(添加隐藏输入框)
@page @model WebStore.Pages.VareModel @{} <br /> <h2 id="title">@(Model.Loc.Location)</h2> <!-- 添加隐藏输入框用于捕获扫描器输入 --> <input type="text" id="scannerInput" style="position:absolute;opacity:0;pointer-events:none;"> <table class="table" id="VareTable"> <thead> <tr> <th>Item</th> <th>Quantity</th> <th>Description</th> <th>EanNum</th> </tr> </thead> <tbody> @foreach (var Info in Model.listItems) { <tr id="@Info.ItemID"> <td>@Info.Item</td> <td>@Info.Qty</td> <td>@Info.Description</td> <td id="@Info.ItemID ean">@Info.EAN</td> </tr> } </tbody> </table>
更新JavaScript
// 确保DOM加载完成后再执行脚本 document.addEventListener('DOMContentLoaded', () => { const scannerInput = document.getElementById('scannerInput'); // 自动聚焦输入框,确保扫描器输入能被捕获 scannerInput.focus(); // 监听input事件捕获扫描内容 scannerInput.addEventListener('input', handleScannerInput); // 监听keyup事件作为Enter键的备用处理 scannerInput.addEventListener('keyup', (event) => { if (event.key === 'Enter') { handleScannerInput(); } }); // 处理扫描输入的核心函数 function handleScannerInput() { let inputValue = scannerInput.value.trim(); // 移除结尾的换行/回车符(扫描器通常会自动添加) inputValue = inputValue.replace(/[\n\r]$/, ''); if (inputValue) { TableIt(inputValue); scannerInput.value = ''; // 清空输入框准备下一次扫描 } } function myFunction(rowId) { const row = document.getElementById(rowId); if (row) { // 用style替代过时的bgcolor属性 row.style.backgroundColor = '#dee'; } } function TableIt(text) { const table = document.getElementById("VareTable"); // 遍历表格行(跳过表头) for (let i = 1; i < table.rows.length; i++) { const row = table.rows[i]; for (let j = 0; j < row.cells.length; j++) { const col = row.cells[j]; // 用textContent替代innerHTML,避免HTML标签干扰匹配 if (col.textContent.trim() === text) { myFunction(row.id); // 直接使用行的ID定位,无需计算索引 return; // 找到匹配后直接退出,提升效率 } } } } });
关键改进点
- 隐藏输入框:确保扫描器输入能被稳定捕获,避免全局事件在移动设备上的兼容性问题。
- 事件选择:
input事件能直接获取输入内容,无需手动拼接字符,更适配扫描器的快速输入模式。 - 内容匹配:使用
textContent替代innerHTML,避免单元格内的HTML结构影响匹配结果。 - 行定位:直接使用行的
id进行定位,不再依赖循环索引计算,避免表头行导致的索引错误。 - 属性替换:用
style.backgroundColor替代过时的bgcolor属性,符合现代Web标准。 - DOM加载时机:确保脚本在DOM完全加载后执行,避免找不到元素的问题。
内容的提问来源于stack exchange,提问作者Ildfugl
相关产品推荐
相关产品推荐

