Archive for the ‘AJAX’ tag
网页中跨域iframe避免相互刷新死循环的方法
最近在做的系统,需要与客户的网页集成,因此牵涉到了跨域访问的问题。所以使用了大量的iframe绕过浏览器的安全策略。
由于跨域系统的安全限制,这些iframe之间是不能相互通信的,需要靠onload事件和父窗口进行交互,而iframe的刷新动作则须由父窗口控制。
其中遇到了一个有意思的问题。大致是这样的:页面打开时,用户没有登录系统,所有的iframe加载后处于未登录状态,点击任意一个iframe,系统会弹出登录画面,登录系统后,需要重新加载这些iframe,从而实现登录状态的同步。
如下面2张图所示:


于是,我在父窗口中写了这样的jquery脚本:
function refresh() {
__self = $(this);
$('iframe.myDomain').each(function(){
if($(this).attr(id) != __self.attr(id)) {
url = $(this).attr('src');
url = url.replace(/\?rand=.*$/, '?rand=' + Math.random());
$(this).attr('src', url);
}
});
}
$('iframe.myDomain').each(function(){
$(this).bind('load', refresh);
});
每当onload事件发生的时候,refresh函数会被触发,然后就会更新其他的iframe。但是,这样做有个重大的问题!如下图所示,当其他的iframe刷新完成的时候,同样会产生onload事件,此时,refresh再次被触发,又去刷新其他的iframe,产生了连锁反应,整个加载动作陷入了死循环!

为了避免这样的死循环,我们需要让接受到刷新指令的iframe在重新加载页面后不向其他iframe再次发送刷新指令,同时又要让其自身做好接受下一个刷新指令的准备。实现的方法很简单,只要稍稍修改我们的js代码即可。
function noRefresh() {
//不触发任何动作的onload事件处理函数
//重新绑定事件处理函数,为下一次处理onload事件做准备。
$(this).unbind('load');
$(this).bind('load', refresh);
}
function refresh() {
__self = $(this);
$('iframe.myDomain').each(function(){
if($(this).attr('id') != __self.attr('id')) {
url = $(this).attr('src')
url = url.replace(/\?rand=.*$/, '?rand=' + Math.random());
//将待刷新的iframe的onload处理函数重新设置
//其自身刷新后,调用noRefresh,防止刷新事件死循环
$(this).unbind('load');
$(this).bind('load', noRefresh);
//现在,刷新时就不会引起连锁反应了。
$(this).attr('src', url);
}
});
}
$('iframe.myDomain').each(function(){
//初始化的时候,关闭所有的onload事件
$(this).bind('load', noRefresh);
});
OK,问题解决!

jQuery? 且慢,css先行!
![]()
前两天开始看jQuery,一开始就被它的优雅设计震撼了。从learningjquery.com下载了源码、换上新发布的jQuery1.3后,却发现有些sample出问题了。仔细一看原来是selector的支持从原来的css+xpath同一到了css。打开源文件,稍加修改,就OK啦:D
jQuery1.3采用了全新的css selector引擎Sizzle,不但直接弥补了浏览器对于css标准selector的支持不足,据说性能也相当强悍!
不过之前对于css一直是一知半解的状态,没有好好花功夫看过,就趁现在系统地学习学习。
贴上Add Bytes的css小抄(这个系列我很喜欢)
