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

JavaScript如何自动适配动态新增输入框的焦点记忆

解决方案

核心思路是无需提前维护input_X数组,在输入框获得焦点时实时计算它在所有.box-ipt元素中的位置,动态生成对应的标识字符串,这样不管HTML中新增多少个输入框,代码都能自动适配,无需手动修改。

修正后的存储焦点代码

window.addEventListener('load', () => {
  // 给所有.box-ipt绑定焦点事件
  document.querySelectorAll('.box-ipt').forEach((input) => {
    input.onfocus = () => {
      // 获取当前input在所有.box-ipt中的索引(从0开始)
      const allInputs = document.querySelectorAll('.box-ipt');
      const index = Array.prototype.indexOf.call(allInputs, input);
      // 生成input_X格式的标识并存入localStorage
      localStorage.setItem('myInputFocused_box1', `input_${index + 1}`);
    };
  });
});

为什么之前的方案有问题?

  1. for循环方案:你提前在页面加载时生成了values数组,但如果后续HTML中新增输入框,新的输入框不会被绑定焦点事件(因为querySelectorAll只在load时执行一次);另外,若页面重新加载时输入框数量变化,虽values会重新生成,但依赖提前生成的数组不如实时计算索引可靠,易因DOM顺序变动导致索引不匹配。
  2. 无限循环方案:这是典型死循环写法,for(;;)会无限制执行,直接导致浏览器资源耗尽崩溃,完全不可行。

整合后的完整代码

将多个load事件监听合并,代码更简洁高效:

// 页面加载完成后执行所有初始化逻辑
window.addEventListener('load', () => {
  // 1. 从localStorage恢复上次的焦点
  const baseanimdur = getComputedStyle(window.parent.document.documentElement).getPropertyValue('--base-anim-dur').replace('s', '');
  const focusDelay = getComputedStyle(document.documentElement).getPropertyValue('--parent-grid-searchbox-focus-onload');
  setTimeout(() => {
    const inputValue = localStorage.getItem("myInputFocused_box1") || "";
    const inputNumber = inputValue.match(/\d+/)?.[0];
    const allInputs = document.querySelectorAll(".box-ipt");
    // 若有存储的编号则对应聚焦,否则聚焦第一个输入框
    const input = inputNumber ? allInputs[inputNumber - 1] : allInputs[0];
    input.focus();
  }, baseanimdur / focusDelay);

  // 2. 绑定输入框焦点事件,实时存储当前焦点的标识
  document.querySelectorAll('.box-ipt').forEach((input) => {
    input.onfocus = () => {
      const allInputs = document.querySelectorAll('.box-ipt');
      const index = Array.prototype.indexOf.call(allInputs, input);
      localStorage.setItem('myInputFocused_box1', `input_${index + 1}`);
    };
  });

  // 3. 点击空白区域(body)时恢复焦点
  const body = document.querySelector('body');
  document.addEventListener('click', event => {
    // 原逻辑中条件判断两边执行相同操作,可简化
    if (event.composedPath().includes(body)) {
      window.getActiveInputOnBTClick();
    }
  });
});

// 点击搜索按钮时恢复焦点的函数
window.getActiveInputOnBTClick = () => {
  const inputValue = localStorage.getItem("myInputFocused_box1");
  const inputNumber = inputValue?.match(/\d+/)?.[0];
  const allInputs = document.querySelectorAll(".box-ipt");
  const input = inputNumber ? allInputs[inputNumber - 1] : allInputs[0];
  input.focus();
};

额外优化点

  • 合并多个window.addEventListener('load', ...),减少重复监听,提升代码执行效率。
  • 在getActiveInputOnBTClick函数中增加对localStorage.getItem结果的空值判断,避免因存储值不存在导致报错。
  • 简化点击body的事件逻辑,原代码中条件判断的两个分支执行相同操作,明确只在点击body时执行聚焦逻辑(若需求是点击任何区域都聚焦,可直接去掉条件,直接调用window.getActiveInputOnBTClick())。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 08:11:27