如何为js-spatial-navigation添加元素间焦点切换的平滑样式
实现平滑切换的焦点轮廓效果
方案1:CSS过渡实现元素自身焦点平滑变化
直接利用:focus伪类和CSS过渡,给焦点元素添加自定义轮廓动画:
- 清除默认焦点样式,避免浏览器自带outline干扰:
.focusable { outline: none; position: relative; padding: 2px; /* 预留轮廓空间,防止内容偏移 */ }
- 用伪元素实现自定义焦点轮廓并添加过渡:
.focusable:focus::after { content: ''; position: absolute; inset: 0; /* 等价于top/left/right/bottom: 0 */ border: 2px solid #0066ff; /* 自定义焦点颜色 */ border-radius: 4px; transition: all 0.2s ease; /* 平滑过渡动画 */ }
方案2:独立焦点跟随容器(贴近示例动图效果)
如果要实现轮廓从一个元素平滑移动到另一个元素的效果,需要用独立DOM元素作为焦点容器,通过监听焦点事件更新其位置:
- 在页面中添加焦点容器:
<div id="focus-outline"></div>
- 编写焦点容器的CSS:
#focus-outline { position: fixed; pointer-events: none; /* 不干扰元素交互 */ border: 2px solid #0066ff; border-radius: 4px; transition: all 0.25s cubic-bezier(0.34, 1.56, 0.64, 1); /* 弹性过渡曲线 */ z-index: 9999; /* 确保在所有元素上层 */ } /* 隐藏原生焦点样式 */ .focusable { outline: none; }
- 修改JS代码,监听焦点切换事件:
window.addEventListener('load', function () { SpatialNavigation.init(); SpatialNavigation.add({ selector: '.focusable', straightOnly: true, straightOverlapThreshold: 0.5, rememberSource: true, }); SpatialNavigation.makeFocusable(); const focusOutline = document.getElementById('focus-outline'); // 监听js-spatial-navigation的焦点切换事件 document.addEventListener('sn:willfocus', (e) => { const rect = e.target.getBoundingClientRect(); // 更新焦点容器的位置与尺寸 Object.assign(focusOutline.style, { left: `${rect.left}px`, top: `${rect.top}px`, width: `${rect.width}px`, height: `${rect.height}px` }); }); // 初始化焦点容器位置 const initialFocus = document.querySelector('.focusable:focus'); if (initialFocus) { const rect = initialFocus.getBoundingClientRect(); Object.assign(focusOutline.style, { left: `${rect.left}px`, top: `${rect.top}px`, width: `${rect.width}px`, height: `${rect.height}px` }); } SpatialNavigation.focus(); });
关键提示
- 若使用React等框架,动态生成
focusable元素后,需调用SpatialNavigation.makeFocusable()重新识别焦点元素。 - 调整
transition的时长和曲线参数,可匹配示例动图的动画节奏。 - 确保
.focusable元素的position不为static(方案1中伪元素定位需要)。
内容的提问来源于stack exchange,提问作者Dharshan PLUV
相关产品推荐
相关产品推荐

