Vue2 键盘导航列表选中项超出视口无法自动滚动定位问题
问题原因
- 只有ArrowDown逻辑中写了定位处理,ArrowUp修改选中索引后没有执行滚动定位
- 若使用
focus()实现定位,需要目标元素支持聚焦,默认的表格行等元素无tabindex属性无法被聚焦,会导致focus无效
解决方案1:无需使用ref(推荐,复用现有选中类名)
你已经给选中的列表项绑定了.teste类名,直接通过类名获取当前选中元素调用原生滚动API即可,无需处理ref的适配问题:
- (如果需要focus效果)给
itemPedido组件的根元素(通常是<tr>标签)添加tabindex="-1"属性,让元素支持聚焦同时不会被Tab键默认触发导航。 - 修改
navegarSetas函数,统一处理上下键的滚动逻辑:
navegarSetas(key) { if (this.navegacaoSetasAtiva == false) { this.navegacaoSetasAtiva = true this.navegacaoAtual = 0 } else if (this.modalAtivado == false && this.navegacaoSetasAtiva == true) { if (key == 'ArrowDown' && this.navegacaoAtual < this.pedidos.length - 1) { this.navegacaoAtual++ } else if (key == 'ArrowUp' && this.navegacaoAtual <= this.pedidos.length && this.navegacaoAtual > 0) { this.navegacaoAtual-- } else if (key == 'Enter') { let pedidoSelecionado = this.pedidos[this.navegacaoAtual].id Event.$emit('changeShow', pedidoSelecionado) return // 回车操作无需滚动 } } // 统一执行滚动定位 this.$nextTick(() => { const activeItem = document.querySelector('.teste') if (!activeItem) return // 滚动到当前选中项,block设为nearest表示元素在视口内时不滚动,超出时滚动到最近的视口边缘 activeItem.scrollIntoView({ block: 'nearest', behavior: 'smooth' // 不需要平滑滚动可以删除该属性 }) // 需要聚焦效果可以加上这行 // activeItem.focus() }) },
解决方案2:使用ref实现
如果坚持用ref的方式,需要注意Vue2中v-for绑定的ref数组和渲染顺序一一对应,修改逻辑如下:
- 同上,给
itemPedido组件根元素加tabindex="-1" - 调整
navegarSetas的定位逻辑,上下键都执行定位,同时加非空判断避免索引越界报错:
navegarSetas(key) { if (this.navegacaoSetasAtiva == false) { this.navegacaoSetasAtiva = true this.navegacaoAtual = 0 } else if (this.modalAtivado == false && this.navegacaoSetasAtiva == true) { if (key == 'ArrowDown' && this.navegacaoAtual < this.pedidos.length - 1) { this.navegacaoAtual++ } else if (key == 'ArrowUp' && this.navegacaoAtual <= this.pedidos.length && this.navegacaoAtual > 0) { this.navegacaoAtual-- } else if (key == 'Enter') { let pedidoSelecionado = this.pedidos[this.navegacaoAtual].id Event.$emit('changeShow', pedidoSelecionado) return } } this.$nextTick(() => { const targetRef = this.$refs.teste?.[this.navegacaoAtual] if (!targetRef) return targetRef.$el.scrollIntoView({ block: 'nearest' }) targetRef.$el.focus() }) },
额外说明
scrollIntoView会自动识别最近的可滚动父容器,不管滚动区域是窗口还是表格外层的固定高度容器都能生效block参数可根据需求调整:start表示滚动到视口顶部,center表示居中,end表示滚动到视口底部
内容的提问来源于stack exchange,提问作者Mirino97
相关产品推荐
相关产品推荐

