ExtJS 7.0 Classic加载遮罩仅单个用户无法关闭问题求助
ExtJS 7.0 Classic加载遮罩无法关闭问题的修复方案
你的问题出在直接操作DOM移除遮罩的方式不可靠——你用Ext.getBody().dom.lastChild.remove()来关闭遮罩,但这个写法完全依赖遮罩是body的最后一个子元素,一旦页面上有其他动态元素(比如弹窗、临时DOM节点)在请求过程中被插入到body末尾,这行代码就会删错元素,导致遮罩留在页面上。这也解释了为什么你在本地浏览器复现不了,但用户那边会出现——用户的环境里可能有你没考虑到的动态DOM变化。
正确的做法是利用ExtJS LoadMask自身提供的API来控制遮罩,而不是直接操作DOM:
- 保留
myMask的引用,在success和failure回调里调用myMask.hide()或者myMask.destroy()来关闭/销毁遮罩 - 更推荐给表单本身加遮罩,而不是整个body,这样范围更精准,也避免和其他页面元素冲突
修改后的代码如下:
loadFormData:function(id, history, callback){ var historyID = 0; if(id==undefined) id = 0; if(history) historyID = id; var form = this.getForm(); form.reset(); // 给表单加遮罩,而非整个body,范围更精准 var myMask = new Ext.LoadMask(form.getEl(), {msg:"Loading..."}); myMask.show(); // 显式显示遮罩,逻辑更清晰 form.load({ url:'fc.php', method:'POST', scope:this, params:{ _C_A:this.loadDataController, _hid:historyID, _uid:id }, success:function(form, action){ this.formData = action.result.data; this.fireEvent('afterFormSaved'); if(typeof(callback)=='function'){ callback(); } // 用LoadMask原生方法关闭遮罩 myMask.hide(); // 若无需复用遮罩,可直接销毁释放资源:myMask.destroy(); }, failure:function(form,action){ // 同样用原生方法关闭遮罩 myMask.hide(); var myMsg = '获取表单数据时出错,请联系支持人员'; if(action.result && action.result.msg) myMsg = action.result.msg; Ext.Msg.show({ title:'表单加载失败', msg:myMsg, icon:Ext.MessageBox.ERROR }) } }); },
关键改动说明:
- 将遮罩绑定到表单元素
form.getEl()而非全局body,避免其他页面动态元素干扰遮罩操作 - 显式调用
myMask.show(),逻辑更清晰(虽然LoadMask实例化后默认会显示,但显式调用更易维护) - 用
myMask.hide()替代直接DOM删除,这是ExtJS官方推荐的遮罩控制方式,稳定性远高于直接操作DOM - 若遮罩无需复用,调用
myMask.destroy()可彻底清理资源,避免内存泄漏
这种写法能彻底解决不同环境下遮罩无法关闭的问题,因为它不依赖DOM节点的顺序,而是通过ExtJS组件的引用直接控制遮罩状态。
内容的提问来源于stack exchange,提问作者Markus W
相关产品推荐
相关产品推荐

