最近两个月来一直有一个BUG纠结在身,就是在系统首页栏目刷新flash图表时总会报“__flash__removeCallback未定义”的错误,而且会重复弹,一直关不掉。
在网上呢也找了很多解决方案,很多都说要在页面重写__flash__removeCallback方法,但是我每个地方都重写了还是报错。后来在这个博客找到了解决方案!
下面我先说问题原因:
因为我们一个系统首页有很多栏目,每个栏目都有一个iframe,每个栏目的格式大概为:
<div id="nodeid">
<div>
<iframe src="xxx" .../>
</div>
</div>
当用户想要刷新指定栏目时,我们的javascript会通过document.getElementById("nodeid").innerHTML="<div>请稍后</div>"这样的方式将<div id="nodeid">栏目中的内容清理掉并重新赋值。每次调用innerHTML的时候就会出现__flash__removeCallback未定义这样的错误,即使加了try...catch都没用,似乎该js错误已经跳出了该代码片段。
后来分析,估计原因是:在执行innerHTML的时候,旧的iframe被销毁,这时flash捕获到被销毁的事件后就会调用__flash__removeCallback方法来处理本身的flash对象(可能是为IE性能考虑),但是因为iframe生命周期已经结束,所以找不到__flash__removeCallback方法,自然就报错了。
然后我按照这位大神的思路去处理,即在渲染图表的JSP页面增加onbeforeunload和onunload事件,在页面加载初期和关闭前执行一次图表div的清理操作,果真不报错了。
<head>
<script>
function removeChart(){
try{
$("#chart").empty();
}catch(e){
}
}
</script>
</head>
<body class="h100b over_hidden" id="body" οnbefοreunlοad="removeChart()" οnunlοad="removeChart()">
然后我调整思路,因为如果每个涉及到flash图表的JSP都修改的话代码非常大,在加载栏目的js中控制最好,那么其实解决思路很简单了:就是在执行document.getElementById("nodeid").innerHTML前找到iframe的body并且清空:
try{ //在iframe销毁前清理掉iframe中的内容(特别是flash) $("#"+this.nodeId+" iframe").contents().find("body").empty(); }catch(e){ } document.getElementById(this.nodeId).innerHTML = "<div>请稍候</div>"; ......
然后测试,怎么刷新都没问题了,妥妥的。
注:该问题在我的IE9浏览器重现,其它浏览器不会出现!