Ionic 3 如何禁用Alert Controller弹窗输入框自动聚焦唤起键盘
问题背景
Ionic 3项目中使用Alert Controller创建带输入项的登录弹窗时,弹窗展示后会自动聚焦到第一个输入框并唤起软键盘,调用present()方法时传入{keyboardClose: true}配置参数无任何效果,需要可禁用该自动聚焦行为的可行方案。
相关实现代码如下:
let alert = self.alertCtrl.create({ title: 'Login', inputs: [ { name: 'location_code', placeholder: 'Location Code', }, { name: 'password', placeholder: 'Password', type: 'password' } ], buttons: [ { text: 'Cancel', role: 'cancel', handler: data => { console.log('Cancel clicked'); } }, { text: 'Login', handler: data => { console.log("Handling Login On Click"); } } ] }); alert.present();
已尝试的无效方案:
this.alertController.create( ... ) .present({ keyboardClose: true });
无效原因说明
keyboardClose: true参数的作用是配置点击弹窗外部遮罩层时是否自动收起软键盘,和弹窗初始化时的自动聚焦逻辑完全无关。Ionic 3的Alert组件默认内置逻辑为:如果弹窗配置了输入项,在present动画播放完成后会主动触发第一个输入框的focus事件,该逻辑没有开放公开配置项直接关闭,需要手动干预实现。
可行解决方案
方案1:弹窗渲染完成后主动移除焦点(适配性最好)
利用present()返回的Promise监听弹窗渲染完成时机,等组件内置的自动聚焦逻辑执行完成后,主动触发输入框blur,必要时可调用原生键盘插件收起键盘。
代码修改如下:
// 原有alert创建逻辑保持不变 alert.present().then(() => { // 延时跳过组件内部focus执行时序,延时可根据项目动画速度调整为100-300ms setTimeout(() => { const activeInput = document.querySelector('.alert-wrapper input:focus') as HTMLInputElement; if (activeInput) { activeInput.blur(); // 若集成了cordova键盘插件,可额外调用原生方法收起键盘 if (window['cordova'] && window['Keyboard']) { window['Keyboard'].close(); } } }, 150); });
方案2:添加隐藏占位输入项承接自动聚焦
在输入项列表最前面添加一个不可见、不可交互的占位输入项,让组件内置的自动聚焦逻辑命中这个无效元素,就不会触发真实业务输入框的聚焦和软键盘唤起。
代码修改如下:
let alert = self.alertCtrl.create({ title: 'Login', // 新增自定义类名用于控制占位项样式 cssClass: 'no-auto-focus-alert', inputs: [ // 新增占位输入项 { name: 'dummy_focus_target', placeholder: '' }, // 原有业务输入项保持不变 { name: 'location_code', placeholder: 'Location Code', }, { name: 'password', placeholder: 'Password', type: 'password' } ], // 原有按钮配置保持不变 buttons: [/* 省略原有按钮代码 */] });
在全局样式文件app.scss中添加对应样式,隐藏占位输入项:
.no-auto-focus-alert .alert-input-wrapper:first-child { position: absolute; width: 0; height: 0; opacity: 0; pointer-events: none; } .no-auto-focus-alert .alert-input-wrapper:first-child input { tab-index: -1; }
注意事项
- 方案1的setTimeout延时不要低于100ms,否则会在组件内部focus逻辑执行前就触发blur,导致方案失效;低版本安卓Webview可适当调高延时到200-300ms适配渲染速度。
- 方案2不需要写延时逻辑,适配性更稳定,但需要额外添加全局样式,注意不要和项目内其他自定义弹窗样式冲突。
内容的提问来源于stack exchange,提问作者Yeo Bryan
相关产品推荐
相关产品推荐

