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

动态创建元素时getElementById失效及表格交互问题求助

动态表格事件绑定与回车交互问题解决

问题描述

根据矩阵单元格数量生成带输入框的表格,遇到两个核心问题:

  • 动态创建的输入框无法触发预先绑定的focus和keyup事件
  • 回车键切换输入框焦点、最后单元格回车新增行的功能存在异常

原代码

HTML代码

<!DOCTYPE html>
<html lang="en">
  <head >
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="src/style.css">
  </head>
  <body onload="tableCreate()">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

    <script src="src/script.js"></script>
  </body>
</html>

JavaScript代码

var c = [
  ['casa', 'casa1', 'casa2'],
  ['casa3', 'casa4', 'casa5'],
  ['casa6', 'casa7', 'casa8'],
  ['casa9', 'casa10', 'casa11'],
];
function tableCreate() {
  const body = document.body,
    tbl = document.createElement('table');
  tbl.setAttribute('id', 'tab_1');
  tbl.style.width = '100px';
  tbl.style.border = '1px solid red';

  for (let i = 0; i < c.length; i++) {
    const tr = tbl.insertRow();
    for (let j = 0; j < 3; j++) {
      const td = tr.insertCell();
      var x = document.createElement('INPUT');
      x.setAttribute('type', 'number');
      x.setAttribute('class', 'username');
      td.appendChild(x);
      td.style.border = '2px solid yellow';
    }
  }
  document.body.appendChild(tbl);
}


$('.username').focus(function (event) {
  console.log('gd');
});



var currentBoxNumber = 0;
$('.username').keyup(function (event) {
  if (event.keyCode == 13) {
    textboxes = $('input.username'); 
    console.log('o');
    currentBoxNumber = textboxes.index(this);
    if (textboxes[currentBoxNumber + 1] != null) {
      nextBox = textboxes[currentBoxNumber + 1];
      nextBox.focus();
      nextBox.select();
      event.preventDefault();
    } else {
     
      const bd = document.body,
      tbl = document.getElementById('tab_1');
      
      const tr = tbl.insertRow();
      for (let j = 0; j < 3; j++) {
        const td = tr.insertCell();
      var x = document.createElement('INPUT');
        x.setAttribute('type', 'number');
        x.setAttribute('class', 'username');
        td.style.border = '2px solid green';
        td.appendChild(x); 
      }
      bd.appendChild(tbl);
    }
    return false;
  }
});

解决方案

1. 采用事件委托绑定动态元素事件

直接通过.username绑定事件只能作用于页面加载时已存在的元素,动态新增的元素需要用事件委托,将事件绑定到父级(或更上层的静态元素),确保后续创建的元素也能触发事件:

// 绑定focus事件
$(document).on('focus', '.username', function(event) {
  console.log('gd');
});

// 绑定keyup事件
var currentBoxNumber = 0;
$(document).on('keyup', '.username', function(event) {
  if (event.keyCode === 13) {
    const textboxes = $('input.username');
    currentBoxNumber = textboxes.index(this);
    
    // 切换到下一个输入框
    if (currentBoxNumber + 1 < textboxes.length) {
      const nextBox = textboxes.eq(currentBoxNumber + 1);
      nextBox.focus();
      nextBox.select();
      event.preventDefault();
    } else {
      // 新增一行并聚焦第一个输入框
      const tbl = document.getElementById('tab_1');
      const tr = tbl.insertRow();
      let newInput;
      
      for (let j = 0; j < 3; j++) {
        const td = tr.insertCell();
        const x = document.createElement('INPUT');
        x.setAttribute('type', 'number');
        x.setAttribute('class', 'username');
        td.style.border = '2px solid green';
        td.appendChild(x);
        
        // 记录新行的第一个输入框
        if (j === 0) {
          newInput = x;
        }
      }
      
      // 聚焦新行的第一个输入框
      newInput.focus();
    }
    return false;
  }
});

2. 优化核心逻辑细节

  • 新增行时无需重复执行bd.appendChild(tbl),表格已存在于DOM中
  • 用textboxes.eq(currentBoxNumber + 1)替代数组索引访问,更符合jQuery操作规范
  • 新增行后自动聚焦到新行的第一个输入框,提升交互流畅度

修改后的完整JavaScript代码

var c = [
  ['casa', 'casa1', 'casa2'],
  ['casa3', 'casa4', 'casa5'],
  ['casa6', 'casa7', 'casa8'],
  ['casa9', 'casa10', 'casa11'],
];
function tableCreate() {
  const body = document.body,
    tbl = document.createElement('table');
  tbl.setAttribute('id', 'tab_1');
  tbl.style.width = '100px';
  tbl.style.border = '1px solid red';

  for (let i = 0; i < c.length; i++) {
    const tr = tbl.insertRow();
    for (let j = 0; j < 3; j++) {
      const td = tr.insertCell();
      var x = document.createElement('INPUT');
      x.setAttribute('type', 'number');
      x.setAttribute('class', 'username');
      td.appendChild(x);
      td.style.border = '2px solid yellow';
    }
  }
  document.body.appendChild(tbl);
}

// 事件委托绑定focus事件
$(document).on('focus', '.username', function(event) {
  console.log('gd');
});

var currentBoxNumber = 0;
// 事件委托绑定keyup事件
$(document).on('keyup', '.username', function(event) {
  if (event.keyCode === 13) {
    const textboxes = $('input.username');
    currentBoxNumber = textboxes.index(this);
    
    if (currentBoxNumber + 1 < textboxes.length) {
      const nextBox = textboxes.eq(currentBoxNumber + 1);
      nextBox.focus();
      nextBox.select();
      event.preventDefault();
    } else {
      const tbl = document.getElementById('tab_1');
      const tr = tbl.insertRow();
      let newFirstInput;
      
      for (let j = 0; j < 3; j++) {
        const td = tr.insertCell();
        const x = document.createElement('INPUT');
        x.setAttribute('type', 'number');
        x.setAttribute('class', 'username');
        td.style.border = '2px solid green';
        td.appendChild(x);
        
        if (j === 0) {
          newFirstInput = x;
        }
      }
      
      newFirstInput.focus();
    }
    return false;
  }
});

内容的提问来源于stack exchange,提问作者Emilio Pantanali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 22:10:34