弹出层插件的编写-layer(跨iframe传值回调)
2014-12-08 09:46
162 查看
弹出层(layer)在往上有非常多,这里为什么我要把它的实现提出来,原因有以下2点:
1、写这篇文章也算是我博客的一个开端,他们都说:“不写博客成不了大神”--
2、我见过的弹出层中都基本没有处理跨iframe传值回调,或者说不是真正意义上的回调函数。
3、一个layer10K左右就可以完成的功能,非得引用一个jqueryEasyUI、jquery等等的方式,都是我不能接受的。
一个独立的插件应该尽量减少依赖,这也是设计模式中追求的解耦与减少依赖。(layer去依赖某种库或多个库,不是一个很好的选择。)
先说说调用方式:插件做出来是让人使用的,我觉得从最终的展现形式入手,能让人更直观的了解这个插件是干嘛的。以及它的优点。
演示代码中我仅仅演示了Iframe弹出层的方式,主要就是看它的回调函数。其它方式,可以在源码中自己查看,稍后将放出源码。
调用方式Code:
上面代码是在index.html页面中的代码,这种场景很多,(比如:订单页面里,需要选择部门的数据,往往会把部门的数据做成一个单独的页面,通过弹出层调用之后选择,然后返回对应的数据)
layer.win是弹出iframe的方式,参数1为弹出层的标题(这个参数其实非常灵活),参数2一看就是一个页面的url,这里设置为callback.html。参数3:这个参数很关键了。它是一个真正意义上的回调函数,也就是当callback.html选择数据返回之后执行的代码。文字比较抽象,还是看代码。
会前端的朋友都能看懂这段代码,非常简单。当点击按钮时:执行了call这个函数,函数内首先获取id为v1的input值,赋值给text变量。然后调用top.layer.callData(location.href,text)
参数1,location.href即当前的url,这个参数是固定的,不会更改的。参数2text,就是刚刚获取到的值。
当调用这个方法时:就会执行上面调用layer.win里的回调函数,这是如何办到的,这应该是我们最关心的话题。
我见过许国其它弹出层的处理方式:
许多弹出层都是这样的处理方式,或者说直接parent.xxx(text),xxx即是父页面的一个函数。原理就是通过parent等方式去定位调用之前的页面,然后直接访问其页面的元素或者方法。
那么:这样做到底有什么问题?可以这样说,这种设计违背了设计模式的很多原则,别看javascript是弱类型语言。其实它很强大!--
那到底哪里违背了?假设我们还是以上面的例子说明:
订单页面里,需要选择部门的数据,当我们选择数据之后执行call时去调用订单页面的,如:parent.document.getElementById("Order-Department").value=data;
单单看上面的代码,貌似也没有什么问题
现在我又有另外一个页面User.html(用户设置页面),同样也需要调用选择部门的页面,首先:我不可能去重写一个部门页面,因为它已经存在了,如果去重写一个,这......我也不好说什么了,如果不重写,那么我们还是调用先前的部门页面,看会发生什么事情。代码可能就会变成这样了:
OK,上面的列子是很常用,很现实的一个例子,如果你是Web系统的开发人员,这种问题基本是不可能不遇到。
很明显:上面的列子违背了太多原则:开放封闭....单一职责原则.......假设还有其它n个页面需要调用到部门选择!假设某天用户页面上的input换了个id!....自己可以想象下!
好了,现在我们回到如何解决这个问题,也就是layer中如何来实现这个真正意义上的回调函数的地方。
翻看源码时你会发现:在调用layer.win方法时,它的第三个参数,也就是回调函数,以这样的代码形式在js中进行了处理:
第三个参数callback以window["layergofunc"+layerobj.config.id]=layerobj.config.iframe.success的形式进行了保存。它给窗口注册了一个对象,对象名称是一个字符串+时间戳的方式(layerobj.config.id实际是一个时间戳)。
而当回调页面执行parent.layer.callData(location.href,text);时,为什么有一个固定的参数location.href。这个我们参考callData方法,看看它干了什么事情:
首先获取了layerid,通过解析了location.href,这里可以猜得到,在调用win方式时,我们为要调用的页面动态的加了一个参数,键值为layer-id。这里通过获取到这个id,然后重新执行了在win方式时注册的window对象。当执行到最后一句代码window["layergofunc"+layerid](temparray);时,实际上就执行了:function(data){document.getElementById("callBox").value+=
data+"\r\n";}这个匿名回调函数。
刚写博文,风格不好,思路也比较乱。不知道有没有解释清楚iframe传值原理。源码我已经提供了下载。这个layer还有很多其它的功能,如果有人有时间做做美化之类的,用它在实际项目中使用来代替模态窗口是个非常不错的选择。首先它小巧,遵循了许多设计上的原则!欢迎留言批判!!!
纯js弹出层附测试demo
1、写这篇文章也算是我博客的一个开端,他们都说:“不写博客成不了大神”--
2、我见过的弹出层中都基本没有处理跨iframe传值回调,或者说不是真正意义上的回调函数。
3、一个layer10K左右就可以完成的功能,非得引用一个jqueryEasyUI、jquery等等的方式,都是我不能接受的。
一个独立的插件应该尽量减少依赖,这也是设计模式中追求的解耦与减少依赖。(layer去依赖某种库或多个库,不是一个很好的选择。)
先说说调用方式:插件做出来是让人使用的,我觉得从最终的展现形式入手,能让人更直观的了解这个插件是干嘛的。以及它的优点。
演示代码中我仅仅演示了Iframe弹出层的方式,主要就是看它的回调函数。其它方式,可以在源码中自己查看,稍后将放出源码。
调用方式Code:
<inputtype="button"onclick="iframe0()"value="iframe层,默认无底部"/>
<textareaid="callBox"style="height:200px"></textarea>
functioniframe0(){ layer.win("回调函数的演示","callback.htm",function(data){ document.getElementById("callBox").value+=data+"\r\n"; }) }
上面代码是在index.html页面中的代码,这种场景很多,(比如:订单页面里,需要选择部门的数据,往往会把部门的数据做成一个单独的页面,通过弹出层调用之后选择,然后返回对应的数据)
layer.win是弹出iframe的方式,参数1为弹出层的标题(这个参数其实非常灵活),参数2一看就是一个页面的url,这里设置为callback.html。参数3:这个参数很关键了。它是一个真正意义上的回调函数,也就是当callback.html选择数据返回之后执行的代码。文字比较抽象,还是看代码。
<htmlxmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <scripttype="text/javascript"> functioncall(){ vartext=document.getElementById("v1").value; top.layer.callData(location.href,text); } </script> </head> <body> <h1>注意:这里是在另外一个页面内</h1> <inputtype="text"id="v1"/> <inputtype="button"value="触发回调函数,真正的父子页面传值"onclick="call()"/> </body> </html>
会前端的朋友都能看懂这段代码,非常简单。当点击按钮时:执行了call这个函数,函数内首先获取id为v1的input值,赋值给text变量。然后调用top.layer.callData(location.href,text)
参数1,location.href即当前的url,这个参数是固定的,不会更改的。参数2text,就是刚刚获取到的值。
当调用这个方法时:就会执行上面调用layer.win里的回调函数,这是如何办到的,这应该是我们最关心的话题。
我见过许国其它弹出层的处理方式:
functioncall(){ vartext=document.getElementById("v1").value;
parent.document.getElementById("callBox").value=text;
}
许多弹出层都是这样的处理方式,或者说直接parent.xxx(text),xxx即是父页面的一个函数。原理就是通过parent等方式去定位调用之前的页面,然后直接访问其页面的元素或者方法。
那么:这样做到底有什么问题?可以这样说,这种设计违背了设计模式的很多原则,别看javascript是弱类型语言。其实它很强大!--
那到底哪里违背了?假设我们还是以上面的例子说明:
订单页面里,需要选择部门的数据,当我们选择数据之后执行call时去调用订单页面的,如:parent.document.getElementById("Order-Department").value=data;
单单看上面的代码,貌似也没有什么问题
现在我又有另外一个页面User.html(用户设置页面),同样也需要调用选择部门的页面,首先:我不可能去重写一个部门页面,因为它已经存在了,如果去重写一个,这......我也不好说什么了,如果不重写,那么我们还是调用先前的部门页面,看会发生什么事情。代码可能就会变成这样了:
functioncall(){ vartext=document.getElementById("v1").value;
if(调用页面==部门页面){
<strong>parent.document.getElementById("Order-<spanleft-pos="0|6"right-pos="0|6"space="">Department</span>").value=text;</strong>
}
elseif(调用页面==用户页面){
<strong>parent.document.getElementById("User-<spanleft-pos="0|6"right-pos="0|6"space=""><spanstyle="background-color:rgb(240,240,240);">Department</span></span>").value=text;</strong>
}
}
OK,上面的列子是很常用,很现实的一个例子,如果你是Web系统的开发人员,这种问题基本是不可能不遇到。
很明显:上面的列子违背了太多原则:开放封闭....单一职责原则.......假设还有其它n个页面需要调用到部门选择!假设某天用户页面上的input换了个id!....自己可以想象下!
好了,现在我们回到如何解决这个问题,也就是layer中如何来实现这个真正意义上的回调函数的地方。
翻看源码时你会发现:在调用layer.win方法时,它的第三个参数,也就是回调函数,以这样的代码形式在js中进行了处理:
this.win=function(parameter,src,callback){
if(typeof(parameter)=="object"){
layerobj.init(parameter);
}
else{
layerobj.config.title=parameter;
layerobj.config.iframe.src=src;
layerobj.config.iframe.success=callback;
}
if(layerobj.config.iframe.success){
window["layergofunc"+layerobj.config.id]=layerobj.config.iframe.success;
}
layerobj.config.type=2;
layerobj.config.btns.count=0;
layerobj.config.oframe.foot=false;
layerobj.run();
returnlayerobj;
}
第三个参数callback以window["layergofunc"+layerobj.config.id]=layerobj.config.iframe.success的形式进行了保存。它给窗口注册了一个对象,对象名称是一个字符串+时间戳的方式(layerobj.config.id实际是一个时间戳)。
而当回调页面执行parent.layer.callData(location.href,text);时,为什么有一个固定的参数location.href。这个我们参考callData方法,看看它干了什么事情:
layer.callData=function(layerid){
if(layerid&&layerid.indexOf("http:")!=-1){
layerid=arguments[0].substring(arguments[0].indexOf("layer-id"),arguments[0].length).split("&")[0].split("=")[1];
}
vartemparguments=[].slice.apply(arguments);
vartemparray=[];
if(temparguments.length>1){
temparray=temparguments.slice(1,temparguments.length);
}
window["layergofunc"+layerid](temparray);
};
首先获取了layerid,通过解析了location.href,这里可以猜得到,在调用win方式时,我们为要调用的页面动态的加了一个参数,键值为layer-id。这里通过获取到这个id,然后重新执行了在win方式时注册的window对象。当执行到最后一句代码window["layergofunc"+layerid](temparray);时,实际上就执行了:function(data){document.getElementById("callBox").value+=
data+"\r\n";}这个匿名回调函数。
刚写博文,风格不好,思路也比较乱。不知道有没有解释清楚iframe传值原理。源码我已经提供了下载。这个layer还有很多其它的功能,如果有人有时间做做美化之类的,用它在实际项目中使用来代替模态窗口是个非常不错的选择。首先它小巧,遵循了许多设计上的原则!欢迎留言批判!!!
相关文章推荐
- 弹出层插件的编写-layer(跨iframe传值回调)
- layer弹出层的iframe页面回调
- 自己编写Jquery弹出层插件,多种自定义...不断更新中...
- layer弹出的iframe层在执行完毕后关闭当前弹出层
- jquery插件封装:弹出iframe模式框
- layer插件如何在弹出层中弹出一警告提示并关闭弹出层
- 在使用layer弹出框时点击按钮后关闭弹出框并刷新父iframe
- 分享国内两个弹出层插件:jbox弹出层,layer弹出层
- layer 弹出iframe层 去掉滚动条
- 编写jquery弹出框插件
- 使用Layer弹出iframe表单窗口,有几率无法成功提交表单问题解决
- 在Vue中使用layer.js弹出层插件
- jQuery提示通知插件jBox弹出iframe的方法总结
- layer (jQuery弹出层插件)使用
- layer.js 贤心制作的弹出层插件-不仅仅是弹层
- 使用 Layer 弹出 iframe 层,并让 iframe 自适应内容宽高
- jquery的layer弹出层框架,如果设置 iframe弹出一个页面里是表单提交,提交完怎么关闭弹出层
- layer---弹出多个iframe如何找到父页面方法
- 不错的一款国产弹出js插件Layer
- 弹出框插件layer使用