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

如何使用jQuery阻止焦点进入指定collapsed类的DOM元素?

阻止焦点进入折叠元素的实现方案

需求说明

现有场景需要:

  • 切换div的collapsed/expanded类名时,expanded状态下允许焦点在内部及页面其他区域正常切换
  • collapsed状态下,完全禁止焦点进入该div及其内部所有可聚焦元素
  • 已实现div获得焦点时切换类名的逻辑

示例HTML结构

<nav>
  <a href="#one">One</a>
  <a href="#two">Two</a>
  <a href="#three">Three</a>
</nav>

<div id="one" tabindex="-1" class="collapsed">
  禁止焦点进入此div及其内部元素
  <button>Button</button>
</div>

<div id="two" tabindex="-1" class="expanded">
  允许焦点在此div内及页面其他区域切换
  <button>Button</button>
</div>

<div id="three" tabindex="-1" class="collapsed">
  禁止焦点进入此div及其内部元素
  <button>Button</button>
</div>

<p>当焦点在div two上时,按Tab键应先聚焦到内部按钮,再跳到这个链接:<a href="#">test link</a></p>

实现方案

1. CSS层基础控制

先通过CSS快速禁用折叠元素的可交互性,同时恢复展开元素的正常状态:

/* 折叠状态下阻止鼠标交互 */
.collapsed {
  pointer-events: none;
}
/* 折叠元素及其内部所有元素强制设为不可聚焦 */
.collapsed,
.collapsed * {
  tabindex: -1;
  outline: none; /* 可选:移除焦点轮廓避免视觉干扰 */
}
/* 展开状态恢复正常交互 */
.expanded {
  pointer-events: auto;
}
/* 展开元素恢复原本的tabindex属性 */
.expanded,
.expanded * {
  tabindex: revert;
}

2. JS层拦截焦点事件

仅靠CSS可能存在边界情况(比如通过JS强制聚焦),所以需要补充JS监听,彻底阻止焦点进入折叠区域:

// 全局捕获焦点事件,优先拦截
document.addEventListener('focus', function(e) {
  // 检查当前元素是否在折叠容器内
  if (e.target.closest('.collapsed')) {
    e.preventDefault();
    e.stopPropagation();
    // 自动跳转到下一个有效可聚焦元素
    const nextEl = getNextValidFocusable(e.target);
    nextEl && nextEl.focus();
  }
}, true);

// 获取下一个非折叠区域的可聚焦元素
function getNextValidFocusable(current) {
  // 筛选所有可聚焦且不在折叠区域内的元素
  const allValid = Array.from(document.querySelectorAll(
    'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
  )).filter(el => !el.closest('.collapsed'));
  
  const currentIdx = allValid.indexOf(current);
  // 循环获取下一个元素,到末尾则回到开头
  return allValid[(currentIdx + 1) % allValid.length];
}

// 保留你原本的类名切换逻辑(示例)
document.querySelectorAll('[tabindex="-1"]').forEach(container => {
  container.addEventListener('focus', function() {
    this.classList.toggle('collapsed');
    this.classList.toggle('expanded');
  });
});

3. 注意事项

  • 如果需要保留折叠div的点击切换功能,给触发切换的元素单独加pointer-events: auto,避免被父级的none覆盖
  • getNextValidFocusable函数确保Tab键跳过折叠元素后,焦点能连续切换,不会出现焦点丢失的情况
  • 使用捕获阶段监听focus事件,能在元素真正获得焦点前就拦截,避免出现短暂的焦点闪烁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 15:31:10