Easyui的messager组件有show,alert,confirm,prompt,progress这几种消息模式,他们的实现方案基本一致,而且生成的DOM结构也都很类似,都是用以下相同样式的DIV做容器的:
<div class="panel window messager-window"></div>
其实这个容器对应的是messager的window对象,销毁window对象的时候便会把这个容器销毁。当然了,页面上可以存在多个这样的消息容器,这也是应有功能。
我们在关闭某个messager的时候,messager组件会自动销毁对应的容器。但是messager.progress的关闭方法却很有意思,它没有办法获取到当前需要关闭的progress对应的容器,所以采用了另可错杀一千不可放走一个的手段,看看messager.progress('close')的源码就一目了然了:
close : function() {
var win = $("body>div.messager-window>div.messager-body");
if (win.length) {
win.window("close");
}
}
看到了吗,$("body>div.messager-window>div.messager-body")这个选择器的威力巨大到,会把所有当前页面的消息容器都关闭,就是说当前页面如果同时存在prompt,comfirm等消息容器的时候也会被messager.progress('close')无情地关闭和销毁,这样当prompt,comfirm自身进行销毁的时候便找不到销毁对象,从而出现脚本错误。
原因分析出来了,但是究竟怎么解决呢?这是个比较麻烦的问题,只有要关闭progress的时候能获取到创建progress时产生的消息容器才行,而目前(1.3.1以及之前的版本)的设计模式我们无法获取到这个容易。
因此我们只能想个折中的办法,算是权益之计,将$("body>div.messager-window>div.messager-body")选择器进一步缩小范围,至少要等跟prompt,confirm等其它消息的容器区分开来。
通过源码的分析,我们发现messager.progress的容器内必定包含messager-progress样式的div,所以我们将选择器做一下改进就可达到目地:
close : function() {
var win = $("div.messager-progress").closest("div.messager-body");
if (win.length) {
win.window("close");
}
}