ExtAspNet应用技巧(四) - 怪异的IE
问题描述:
最近我一直被 ExtAspNet 中一个怪异的问题所困扰,有很多网友遇到这个问题:
http://www.cnblogs.com/sanshi/archive/2009/07/14/1523634.html?login=1#1593949
http://www.cnblogs.com/sanshi/archive/2009/07/14/1523634.html?login=1#1596122
http://extaspnet.codeplex.com/WorkItem/View.aspx?WorkItemId=5185
问题也很怪异,页面http://extasp.net/data/grid_iframe.aspx 中点击“编辑”,会弹出一个窗口,
窗口中加载一个IFrame页面,如下图所示:
但就是这个弹出窗口中的IFrame页面,很多网友反映第一次为空白,必须重新点击一次“编辑”才能显示IFrame页面。并且这个问题只在IE7下出现。
在Firefox,Chrome和IE8下都没这个问题。
我自己觉得更奇怪的是我新装的IE7居然没这个问题,反倒是Maxthon和IETester有这个问题。
=================================================================
解决思路:
1. 对比找到差异
我首先想到的是另外一个页面 http://extasp.net/iframe/grid_iframe.aspx 也有类似的弹出窗口的功能,但是就没有上述问题。于是我第一个做的就是
把两个页面的源代码拿来对比,看有哪些不一样。终于发现正确的页面ext:Window设置为 Target="_parent" (也就是说弹出窗口在父页面弹出),而出现问题
的页面的 ext:Window 的Target="_self" (也就是在本页面弹出窗口)。
虽然找到了出错的地方,但这不是根本的解决办法。
2. 页面寻找思路
还是回到页面,因为本机IE7下还是重现不了这个问题,只有Maxthon下才有,而Maxthon下貌似没有啥可用的开发工具(比如IEDeveloperToolbar,第一次用Maxthon不太了解),
只能眼睁睁的等着空白的页面:
对于开发人员来讲,这是一件多么痛苦的事情,没有一件可用的调试工具(即使给我一个Firebug的lite版本也行啊)。
不过,事情还不至于太糟糕,首先我想确定的是页面是不是已经加载了,在空白处点击 右键->"查看源代码" ,发现整个HTML都是对的,
为什么会不显示呢?然后我尝试 右键->"刷新",页面居然可能正常加载。
郁闷。
3. 还是看看底层JS吧
打开ExtAspNet\js\box\ExtAspNet-Window.js,找到设置弹出窗口中IFrame的地方:
我想看下是否代码执行到 panel.body.dom.innerHTML = ... ,就在这个代码的后面加上了著名的
这一刻,我都高兴的快要跳起来了。
因为我想起IE那个臭名昭著的BUG,如果一段JavaScript在IE下出现了问题,而在其他浏览器中是正常的,那么
就用setTimeout延迟执行吧。
最终,我们用下面的代码完美解决这个问题:
happy coding.
注:请从 SVN 下载最新源代码。
最近我一直被 ExtAspNet 中一个怪异的问题所困扰,有很多网友遇到这个问题:
http://www.cnblogs.com/sanshi/archive/2009/07/14/1523634.html?login=1#1593949
http://www.cnblogs.com/sanshi/archive/2009/07/14/1523634.html?login=1#1596122
http://extaspnet.codeplex.com/WorkItem/View.aspx?WorkItemId=5185
问题也很怪异,页面http://extasp.net/data/grid_iframe.aspx 中点击“编辑”,会弹出一个窗口,
窗口中加载一个IFrame页面,如下图所示:
但就是这个弹出窗口中的IFrame页面,很多网友反映第一次为空白,必须重新点击一次“编辑”才能显示IFrame页面。并且这个问题只在IE7下出现。
在Firefox,Chrome和IE8下都没这个问题。
我自己觉得更奇怪的是我新装的IE7居然没这个问题,反倒是Maxthon和IETester有这个问题。
=================================================================
解决思路:
1. 对比找到差异
我首先想到的是另外一个页面 http://extasp.net/iframe/grid_iframe.aspx 也有类似的弹出窗口的功能,但是就没有上述问题。于是我第一个做的就是
把两个页面的源代码拿来对比,看有哪些不一样。终于发现正确的页面ext:Window设置为 Target="_parent" (也就是说弹出窗口在父页面弹出),而出现问题
的页面的 ext:Window 的Target="_self" (也就是在本页面弹出窗口)。
虽然找到了出错的地方,但这不是根本的解决办法。
2. 页面寻找思路
还是回到页面,因为本机IE7下还是重现不了这个问题,只有Maxthon下才有,而Maxthon下貌似没有啥可用的开发工具(比如IEDeveloperToolbar,第一次用Maxthon不太了解),
只能眼睁睁的等着空白的页面:
对于开发人员来讲,这是一件多么痛苦的事情,没有一件可用的调试工具(即使给我一个Firebug的lite版本也行啊)。
不过,事情还不至于太糟糕,首先我想确定的是页面是不是已经加载了,在空白处点击 右键->"查看源代码" ,发现整个HTML都是对的,
为什么会不显示呢?然后我尝试 右键->"刷新",页面居然可能正常加载。
郁闷。
3. 还是看看底层JS吧
打开ExtAspNet\js\box\ExtAspNet-Window.js,找到设置弹出窗口中IFrame的地方:
// 创建或更新IFrame节点,同时更新panel实例中的自定义属性值
box.wnd.updateIFrameNode = function(panel, iframeUrl) {
if (panel['box_property_iframe']) {
// 如果此Panel中包含有IFrame
if (!panel['box_property_iframe_loaded']) {
// 如果此Panel中包含的IFrame还没有加载
if (iframeUrl) {
panel['box_property_iframe_url'] = iframeUrl;
}
panel['box_property_iframe_loaded'] = true;
panel.body.dom.innerHTML = _createIFrameHtml(panel['box_property_iframe_url'], panel['box_property_iframe_name']);
}
else {
// 如果IFrame已经加载,则更新
if (iframeUrl) {
panel['box_property_iframe_url'] = iframeUrl;
panel.body.first().dom.src = iframeUrl;
}
}
}
};
box.wnd.updateIFrameNode = function(panel, iframeUrl) {
if (panel['box_property_iframe']) {
// 如果此Panel中包含有IFrame
if (!panel['box_property_iframe_loaded']) {
// 如果此Panel中包含的IFrame还没有加载
if (iframeUrl) {
panel['box_property_iframe_url'] = iframeUrl;
}
panel['box_property_iframe_loaded'] = true;
panel.body.dom.innerHTML = _createIFrameHtml(panel['box_property_iframe_url'], panel['box_property_iframe_name']);
}
else {
// 如果IFrame已经加载,则更新
if (iframeUrl) {
panel['box_property_iframe_url'] = iframeUrl;
panel.body.first().dom.src = iframeUrl;
}
}
}
};
我想看下是否代码执行到 panel.body.dom.innerHTML = ... ,就在这个代码的后面加上了著名的
alert("haha");
结果,在我回到页面点击“编辑”时,首先弹出alert,然后正确加载IFrame,没有任何问题。这一刻,我都高兴的快要跳起来了。
因为我想起IE那个臭名昭著的BUG,如果一段JavaScript在IE下出现了问题,而在其他浏览器中是正常的,那么
就用setTimeout延迟执行吧。
最终,我们用下面的代码完美解决这个问题:
box.wnd.updateIFrameNode = function(panel, iframeUrl) {
if (panel['box_property_iframe']) {
// 如果此Panel中包含有IFrame
if (!panel['box_property_iframe_loaded']) {
// 如果此Panel中包含的IFrame还没有加载
if (iframeUrl) {
panel['box_property_iframe_url'] = iframeUrl;
}
panel['box_property_iframe_loaded'] = true;
window.setTimeout(function() {
panel.body.dom.innerHTML = _createIFrameHtml(panel['box_property_iframe_url'], panel['box_property_iframe_name']);
}, 0);
}
else {
// 如果IFrame已经加载,则更新
if (iframeUrl) {
panel['box_property_iframe_url'] = iframeUrl;
panel.body.first().dom.src = iframeUrl;
}
}
}
};
if (panel['box_property_iframe']) {
// 如果此Panel中包含有IFrame
if (!panel['box_property_iframe_loaded']) {
// 如果此Panel中包含的IFrame还没有加载
if (iframeUrl) {
panel['box_property_iframe_url'] = iframeUrl;
}
panel['box_property_iframe_loaded'] = true;
window.setTimeout(function() {
panel.body.dom.innerHTML = _createIFrameHtml(panel['box_property_iframe_url'], panel['box_property_iframe_name']);
}, 0);
}
else {
// 如果IFrame已经加载,则更新
if (iframeUrl) {
panel['box_property_iframe_url'] = iframeUrl;
panel.body.first().dom.src = iframeUrl;
}
}
}
};
happy coding.
注:请从 SVN 下载最新源代码。