会读到本文的朋友,想必是正在使用layer或者对layer已经有一定的熟悉程度了,既然如此,唠家常的话就不说了,我们直接入主题。
layer的弹窗,有一个full方法,可以让我们的弹窗铺满整个屏幕,这对我们弹出一个内容比较多的页面时,显得十分有用,因为我们有了更多展示内容的空间。但layui官网提供的layer,存在一个问题,就是当你调用了full方法之后,虽然能全屏,但是却不再支持窗口的响应了,就是当我们改变窗口大小时,弹层不会跟着窗口进行放大缩小,这就是今天我们要解决的问题。
解决办法,当然是改写layer.js了,因为我们是添加一个功能,不是改写功能,对已有的代码不会造成任何负面影响,所以这也是一个不错的选择。查看layer的源码,我们可以找到对应的full方法,代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//全屏
layer.full=function(index){
varlayero=$('#'+doms[0]+index),timer;
ready.record(layero);
if(!doms.html.attr('layer-full')){
doms.html.css('overflow','hidden').attr('layer-full',index);
}
clearTimeout(timer);
timer=setTimeout(function(){
varisfix=layero.css('position')==='fixed';
layer.style(index,{
top:isfix?0:win.scrollTop(),
left:isfix?0:win.scrollLeft(),
width:win.width(),
height:win.height()
},true);
layero.find('.layui-layer-min').hide();
},100);
};
这代码还算简单,相信大家一看就能发现,setTimeout方法里的代码,就是真正的全屏逻辑了。那我们现在要做的,当然是在窗口改变的时候,也执行一次上面的代码,就像这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//全屏
layer.full=function(index){
varlayero=$('#'+doms[0]+index),timer;
ready.record(layero);
if(!doms.html.attr('layer-full')){
doms.html.css('overflow','hidden').attr('layer-full',index);
}
clearTimeout(timer);
timer=setTimeout(function(){
varisfix=layero.css('position')==='fixed';
layer.style(index,{
top:isfix?0:win.scrollTop(),
left:isfix?0:win.scrollLeft(),
width:win.width(),
height:win.height()
},true);
layero.find('.layui-layer-min').hide();
},100);
window.onresize=function(){
varisfix=layero.css('position')==='fixed';
layer.style(index,{
top:isfix?0:win.scrollTop(),
left:isfix?0:win.scrollLeft(),
width:win.width(),
height:win.height()
},true);
layero.find('.layui-layer-min').hide();
}
};
如果只从功能上来说,上面的代码已经OK了,但还存在着一个优化问题和隐患,优化就是代码重复功能需要提取出来,隐患就是window.onresize方法只能添加一次,如果我们在别的地方也写了相应的window.onresize方法,则我们的代码将被覆盖掉,等于没用了,这显然是不可以的。解决办法就是用$(window).resize()替代,改为下面这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//全屏
layer.full=function(index){
varlayero=$('#'+doms[0]+index),timer;
ready.record(layero);
if(!doms.html.attr('layer-full')){
doms.html.css('overflow','hidden').attr('layer-full',index);
}
clearTimeout(timer);
function_full(){
varisfix=layero.css('position')==='fixed';
layer.style(index,{
top:isfix?0:win.scrollTop(),
left:isfix?0:win.scrollLeft(),
width:win.width(),
height:win.height()
},true);
layero.find('.layui-layer-min').hide();
}
timer=setTimeout(_full,100);
$(window).resize(_full);
};
这样,代码也精简了,覆盖的问题也解决了,按道理说,这已经很OK了。但我们既然改都改了,何不改得更优雅一些呢,那就是处理一下节流的问题。如果你不知道什么是节流,那最好自行科普一下,因为对一个前端开发来说,这是必须考虑的问题。附上最终修改的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//全屏
layer.full=function(index){
varlayero=$('#'+doms[0]+index),timer;
ready.record(layero);
if(!doms.html.attr('layer-full')){
doms.html.css('overflow','hidden').attr('layer-full',index);
}
clearTimeout(timer);
function_full(){
varisfix=layero.css('position')==='fixed';
layer.style(index,{
top:isfix?0:win.scrollTop(),
left:isfix?0:win.scrollLeft(),
width:win.width(),
height:win.height()
},true);
layero.find('.layui-layer-min').hide();
}
timer=setTimeout(_full,100);
//因为这里的节流函数只在这里使用,所以就写得简单
function_throttle(fn,interval){
var_self=fn;//保存需要被延迟执行的函数引用
varfirstTime=true;//是否初次调用
vart;//定时器
returnfunction(){
varargs=arguments;
var_me=this;
if(firstTime){//如果是第一次调用不需要延迟执行
_self.call(_me,args);
}if(t){//如果定时器还在,说明前一次延迟执行还没有完成
returnfalse
}
t=setTimeout(function(){//延迟一段时间执行
clearTimeout(t)//清除定时器 避免下一次return false
t=null;
_self.call(_me,args)
},interval||300)
}
}
$(window).resize(_throttle(_full));
};
好了,本文到此结束,提供一个改写好的下载地址:全屏自适应layer-fullresize.js,需要的朋友可自行下载。还是那句话,如果觉得对你有帮助,记得顺手给个star,毕竟星星越多,分享的动力越大。如果你在使用layui开发项目,可能下面两篇文章也对你有帮助哦。