Ionic 4中Google Autocomplete预测列表随页面滚动问题解决
解决Ionic 4中Google Autocomplete列表随页面滚动问题
问题根源
Google Places的pac-container默认使用absolute定位且挂载在<body>标签下,当Ionic的ion-content滚动时,该容器不会跟随搜索框位置变化,而是基于整个页面的固定位置,导致出现跟随页面滚动的异常。
解决方案
方案1:修改容器定位为fixed并动态计算位置
- 在全局样式文件(
global.scss)中覆盖默认样式:
.pac-container { position: fixed !important; z-index: 9999 !important; /* 确保层级高于Ionic内容 */ top: auto !important; left: auto !important; width: auto !important; }
- 在组件中监听搜索框聚焦事件,动态设置容器位置:
import { ElementRef, ViewChild, OnInit } from '@angular/core'; @Component({ // 组件元数据 }) export class YourComponent implements OnInit { @ViewChild('searchbar') searchbar: ElementRef; ngOnInit() { this.loadAutocomplete(); } loadAutocomplete() { // 你的原有代码... } onSearchFocus() { setTimeout(() => { const pacContainer = document.querySelector('.pac-container'); if (!pacContainer) return; const searchRect = this.searchbar.nativeElement.getBoundingClientRect(); pacContainer.style.top = `${searchRect.bottom + 8}px`; pacContainer.style.left = `${searchRect.left}px`; pacContainer.style.width = `${searchRect.width}px`; }, 100); } }
- 模板中绑定事件和引用:
<ion-searchbar #searchbar (ionFocus)="onSearchFocus()" [(ngModel)]="searchText"></ion-searchbar>
方案2:滚动时隐藏结果列表
页面滚动时直接隐藏预测列表,滚动停止后若搜索框仍聚焦则恢复显示:
- 模板中绑定滚动事件:
<ion-content (ionScroll)="onScroll()"> <ion-searchbar #searchbar [(ngModel)]="searchText"></ion-searchbar> </ion-content>
- 组件中实现滚动逻辑:
import { ElementRef, ViewChild, OnDestroy } from '@angular/core'; @Component({ // 组件元数据 }) export class YourComponent implements OnDestroy { @ViewChild('searchbar') searchbar: ElementRef; private scrollTimeout: any; onScroll() { const pacContainer = document.querySelector('.pac-container'); if (!pacContainer) return; pacContainer.style.display = 'none'; clearTimeout(this.scrollTimeout); this.scrollTimeout = setTimeout(() => { const searchInput = this.searchbar.nativeElement.querySelector('input'); if (searchInput === document.activeElement) { pacContainer.style.display = 'block'; // 重新计算位置 const searchRect = this.searchbar.nativeElement.getBoundingClientRect(); pacContainer.style.top = `${searchRect.bottom + 8}px`; pacContainer.style.left = `${searchRect.left}px`; pacContainer.style.width = `${searchRect.width}px`; } }, 300); } ngOnDestroy() { if (this.scrollTimeout) clearTimeout(this.scrollTimeout); } }
方案3:将容器挂载到搜索框父元素下
让pac-container相对于搜索框的父容器定位,彻底解决滚动跟随问题:
- 给搜索框父容器添加样式:
.search-container { position: relative; z-index: 9999; width: 100%; }
- 模板中包裹搜索框:
<div class="search-container"> <ion-searchbar #searchbar [(ngModel)]="searchText"></ion-searchbar> </div>
- 修改
loadAutocomplete方法,移动容器到父元素中:
loadAutocomplete() { const autocompleteInputNative: HTMLInputElement = this.autocompleteInput._searchbarInput.nativeElement; const options = { componentRestrictions: { country: "br" }, fields: ["formatted_address", "address_components", "geometry"], types: ["address"], bounds: this.bounds, strictBounds: true }; const autocomplete = new google.maps.places.Autocomplete(autocompleteInputNative, options); autocomplete.addListener('place_changed', () => { this.autoCompleteSelected(autocomplete); }); // 监听预测面板生成事件,移动容器 google.maps.event.addListener(autocomplete, 'predictions_changed', () => { setTimeout(() => { const pacContainer = document.querySelector('.pac-container'); const searchContainer = document.querySelector('.search-container'); if (pacContainer && searchContainer) { searchContainer.appendChild(pacContainer); pacContainer.style.position = 'absolute'; pacContainer.style.top = 'calc(100% + 4px)'; pacContainer.style.left = '0'; pacContainer.style.width = '100%'; pacContainer.style.z-index = '9999'; } }, 0); }); }
内容的提问来源于stack exchange,提问作者Victor Soares
相关产品推荐
相关产品推荐

