You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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事件的支持存在差异,且扫描器在移动设备上的输入模拟方式可能与桌面端不同。以下是针对性的修改方案:

核心思路

  1. 使用隐藏的输入框捕获扫描器输入:移动设备对输入框的事件支持更稳定,扫描器通常会自动将内容输入到聚焦的输入框中。
  2. 优先监听input事件捕获内容,同时保留keyup作为备用方案。
  3. 优化内容匹配和行定位逻辑,避免依赖索引计算,提升可靠性。

修改后的代码

更新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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 21:11:07