
本文介绍如何使用原生 javascript 和 php 实现:页面加载时渲染含输入框的首行表格,用户输入条形码后,通过 ajax 异步查询数据库并填充对应商品信息,同时自动追加下一行空白输入行。全程无需 jquery,代码简洁可扩展。
要实现“逐行添加 + 条形码驱动数据填充”的交互式表格,核心在于三步协同:HTML 结构初始化 → 用户输入触发 AJAX 请求 → 后端响应后更新当前行 + 动态插入新行。下面以专业、可落地的方式逐步说明。
✅ 1. 前端 HTML 与初始结构
确保表格拥有唯一 ID(如 id="products"),首行使用 绑定 onchange 事件,并为后续动态行预留语义化 ID(如 product1、amount1):
| barcode | product | amount | price |
|---|---|---|---|
⚠️ 注意:onchange 在用户失焦时触发(更稳妥);若需实时响应,可用 oninput + 防抖,但需自行处理重复请求。
✅ 2. 原生 JavaScript 核心逻辑(无 jQuery)
以下函数构成闭环流程:
- onBarcodeChange(id):接收行序号,发起 AJAX 请求,填充本行数据,并调用 addTableRow() 创建下一行;
- addTableRow(id):动态创建新
,含带 onchange 的输入框及空单元格; - 使用 fetch() 替代过时的 XMLHttpRequest,更现代、简洁。
async function onBarcodeChange(id) { const input = document.querySelector(`#barcode${id} input`) || document.querySelector(`tr:nth-child(${id}) td:first-child input`); const barcode = input?.value.trim(); if (!barcode) return; try { // ? 发起 AJAX 请求(PHP 后端接口) const response = await fetch('get_product.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `barcode=${encodeURIComponent(barcode)}` }); if (!response.ok) throw new Error('Network response was not ok'); const data = await response.json(); // ✅ 填充当前行(根据 ID 定位) document.getElementById(`product${id}`).textContent = data.product || '-'; document.getElementById(`amount${id}`).textContent = data.amount || '0'; document.getElementById(`price${id}`).textContent = `${data.price || '0'} $`; // ➕ 追加下一行(ID 自增) addTableRow(id + 1); } catch (err) { alert(`Error loading product: ${err.message}`); console.error(err); } } function addTableRow(id) { const row = document.createElement('tr'); // 第一列:带事件的输入框 const barcodeCell = document.createElement('td'); barcodeCell.style.textAlign = 'center'; const input = document.createElement('input'); input.type = 'text'; input.placeholder = 'Enter barcode'; input.id = `barcode${id}`; input.onchange = () => onBarcodeChange(id); barcodeCell.appendChild(input); // 其余三列:空单元格(带 ID 便于后续填充) const cellNames = ['product', 'amount', 'price']; const otherCells = cellNames.map(name => { const td = document.createElement('td'); td.id = `${name}${id}`; td.style.textAlign = 'center'; return td; }); // 拼接整行 [barcodeCell, ...otherCells].forEach(td => row.appendChild(td)); document.getElementById('products').querySelector('tbody').appendChild(row); input.focus(); // 自动聚焦新输入框,提升体验 }✅ 3. PHP 后端接口(get_product.php)
该文件接收条形码,查询 MySQL 并返回 JSON:
'Missing barcode']); exit; } $barcode = trim($_POST['barcode']); // ✅ 使用 PDO(推荐)或 mysqli —— 此处以 PDO 为例 try { $pdo = new PDO("mysql:host=localhost;dbname=your_db", "username", "password"); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $stmt = $pdo->prepare("SELECT product_name, amount, price FROM products WHERE barcode = ?"); $stmt->execute([$barcode]); $row = $stmt->fetch(PDO::FETCH_ASSOC); if ($row) { echo json_encode([ 'product' => htmlspecialchars($row['product_name']), 'amount' => (int)$row['amount'], 'price' => (float)$row['price'] ]); } else { echo json_encode(['product' => 'Not found', 'amount' => 0, 'price' => 0]); } } catch (PDOException $e) { error_log('DB Error: ' . $e->getMessage()); http_response_code(500); echo json_encode(['error' => 'Database error']); } ?>✅ 安全提示:务必使用预处理语句防止 SQL 注入;输出前用 htmlspecialchars() 防 XSS。
✅ 4. 补充建议与最佳实践
- 用户体验优化:在 onBarcodeChange 开始时禁用输入框、显示 loading 文本,响应后恢复;
- 错误处理强化:对空结果、网络超时、HTTP 错误码做分层提示;
- 键盘支持:监听 Enter 键提交(input.addEventListener('keypress', e => e.key === 'Enter' && e.target.dispatchEvent(new Event('change'))));
- 性能考虑:若单页行数较多(>50),建议虚拟滚动或分页,避免 DOM 过载。
至此,你已拥有一套轻量、安全、可维护的“扫码即填表”解决方案——完全基于原生技术栈,零第三方依赖,可直接集成到现有 PHP 项目中。










