虽说生成一个代理页没什么难度,更何况它可以是空白的页面。但作为一个组件,这也算是一种约束。约束越少越好。经我研究,有两个URL可以算是本域的永久地址,一个是/favicon.ico(IE下不行),另一个是about:blank。我们就用about:blank作为代理页!
下面是实现:
(function
() {
//数据发送页的URL,回调,加用于opera的延时时间(可选)
var
UIloader =
function
( url, callback, operatime){
if
(
typeof
url ===
"string"
&&
typeof
callback ==
"function"
){
url += (url.indexOf(
'?'
) > 0 ?
'&'
:
'?'
) +
'_time'
+
new
Date * 1;
operatime =
typeof
operatime ===
"number"
? operatime : 3000;
var
el = document.createElement(
'iframe'
), data;
function
receive(e){
e = e || event;
el._state = 2;
callback(e.data)
if
(window.removeEventListener){
window.addEventListener(
'message'
, receive,
false
)
}
else
{
window.detachEvent(
'onmessage'
, receive);
}
body.removeChild(el)
}
if
(window.addEventListener ){
window.addEventListener(
'message'
, receive,
false
)
}
else
{
window.attachEvent(
'onmessage'
, receive);
}
el.style.display =
"none"
;
el._state = 0;
var
body = document.body || document.documentElement;
body.insertBefore( el, body.firstChild );
;(
function
( node, type, fn ) {
if
( window.VBArray ) {
node.attachEvent(
'on'
+ type, fn);
}
else
{
node.addEventListener(type, fn,
false
);
}
})(el,
'load'
,
function
eee() {
if
(el._state === 1 ) {
try
{
data = el.contentWindow.name;
}
catch
(e) {}
el._state = 2;
callback(data)
callback =
function
(){}
body.removeChild(el)
}
else
if
(el._state === 0) {
setTimeout(
function
(){
el._state = 1;
el.contentWindow.location.replace(
"about:blank"
)
}, (window.opera ? operatime : 31) )
//必须等iframe的资源都加载完才跳转,opera显然load触发时机不对
}
});
el.src = url;
}
else
{
throw
"arguments error"
}
}
UIloader(
http://my.oschina.net/u/248095
,
function
(a
){
window.console && console.log(a+
"!!!!!!!!!!!!!"
)
})
})();
现场实例观摩:数据请求页,数据发送页,具体代码见页面源码!然后我们就会在数据请求页的控制台看到打印日志了!
再说回来,为什么叫做UIloader呢,因为一般的跨域数据传送,使用JSONP就够了,非常轻便!但对于UI组件,比如grid,它通常包括一个体积也够为吓人的JS文件,还有一个样式表,如果不想通过字符串拼接来渲染界面,我们还可能用到前端模板,当然还有图片什么的。撇开图片不谈,JS,前端模板,样式我们都可以统统整到一个JS文件里面的,但会显然很乱,尤其是大段的CSS样式,HTML字段,这是不是用HTML来放置它们比较好呢。我们用一个HTML来放置它们,样式表写到style标签中,HTML写到一个DIV上,脚本写到一个script中。那么它们它们拼成一个对象:
var
data = {
html: div.innerHTML,
js: script.text,
css: style.cssText
}
window.name = data
if
(window.postMessage){
window.parent.postMessage(data,
"*"
);
}
|
不过需要注意的是postMessage在IE下只能传字符串,我们只好在发送页统一返回字符串,用JSON.stringify转换一下就行了,取回来再用JSON.parse变成对象!