使用上下箭头导航搜索栏列表时禁用页面滚动的问题求助
问题分析与解决方案
问题原因
- 全局页面滚动:按下上下箭头时,浏览器默认的页面滚动行为未被阻止,导致页面随按键操作滚动。
- 列表滚动异常:
- 滚动容器高度计算错误:
.ui-search-bar__wrapper设置了padding-top:60px,但内部滚动容器未设置对应高度,导致可滚动区域被挤压,元素显示异常。 - 聚焦元素未自动滚动:导航到新元素时,未触发滚动容器的滚动逻辑,导致元素移出可视区域。
- 滚动容器高度计算错误:
- 导航数据过期:过滤产品后,子元素数量未实时更新,导致导航逻辑出现索引错误。
解决方案
1. 阻止箭头按键的默认行为
修改模板中的按键绑定,传递事件对象,并在导航方法中阻止默认滚动行为:
模板修改:
<input aria-label="Pesquisar por produto" class="ui-input" @focus="enableArrowNavigation" placeholder="Pesquisar" type="text" v-model="search" @keydown.up="navigateUp($event)" @keydown.down="navigateDown($event)" /> <!-- 列表项中的a标签同步修改 --> <a :href="grandchild.route" @keydown.up="navigateUp($event)" @keydown.down="navigateDown($event)" tabindex="-1" v-if="grandchild.quantity > 0" >
脚本修改:
navigateDown(event) { event.preventDefault(); this.selected_child = this.selected_child === this.amount_of_children ? 1 : this.selected_child + 1; this.navigate(); }, navigateUp(event) { event.preventDefault(); this.selected_child = this.selected_child > 1 ? this.selected_child - 1 : this.amount_of_children; this.navigate(); },
2. 修正滚动容器的CSS样式
调整.ui-search-bar__wrapper及其内部容器的样式,确保滚动区域高度正确:
.ui-search-bar__wrapper { background-color: white; border-radius: 8px; box-shadow: 0px 0px 12px -5px #1d283a; display: none; left: 0; max-height: 500px; padding-top: 60px; position: absolute; top: 0; width: 100%; overflow: hidden; /* 隐藏溢出内容,确保内部滚动容器高度计算正确 */ & > div { overflow-y: auto; padding-inline: 10px; width: 100%; height: calc(100% - 60px); /* 减去顶部padding,匹配父容器高度 */ } // 原有其他样式保持不变 }
3. 优化导航时的滚动逻辑
修改navigate方法,让聚焦元素自动滚动到可视区域:
navigate() { const activeLink = document.querySelectorAll(".ui-search-bar__children a")[this.selected_child - 1]; if (activeLink) { activeLink.focus(); // 将元素滚动到容器可视区域,避免移出视野 activeLink.scrollIntoView({ block: 'nearest', behavior: 'instant' }); } },
4. 实时更新子元素数量
在过滤产品后,更新子元素数量并重置选中状态:
filterItems(needle) { this.copied_parents = this.makeParentCopy(); const filtered_items = this.copied_parents.filter((parent) => { const children = parent[this.children_key].filter((child) => { const grandchildren = child[this.grandchildren_key].filter((product) => { return product.title.toLowerCase().includes(needle.toLowerCase()); }); child[this.grandchildren_key] = grandchildren; return grandchildren.length > 0; }); parent[this.children_key] = children; return children.length > 0; }); // 过滤完成后更新子元素数量 this.$nextTick(() => { this.amount_of_children = document.querySelectorAll(".ui-search-bar__children a").length; this.selected_child = 0; }); return filtered_items; },
内容的提问来源于stack exchange,提问作者Bernardo Benini Fantin
相关产品推荐
相关产品推荐

