2.7K Star 16K Fork 3.6K

GVPLayui / layui

 / 详情

layer弹出层中表单select控制的option列表被遮盖的问题

已完成
创建于  
2023-05-30 16:54

版本号

2.6.8

问题描述

layer弹出层中表单select控制的option列表被遮盖的问题,怎么处理让下拉框始终在最前面?如果在表单中用dropdown能解决吗?
输入图片说明

业务代码

index2 = layer.open({
type: 1,
id:'searchQuery',
title: '查询条件',
area: ['400px','500px'],
resize: false,
closeBtn: 2,
btn: ['确定', '取消'],
yes: function (index, layero, that) {
sdata = form.val('queryForm');
//console.log(sdata);
layer.close(index2);
ReloadData();
},
content: msg,
success: function (layero, index) {
calcSelectHeight(layero);
}
});

其他补充

友好承诺

我承诺将本着相互尊重、理解和友善的态度进行交流,共同维护 Layui 良好的社区氛围。

评论 (54)

keqing4019 创建了任务
keqing4019 修改了描述
展开全部操作日志

在success里面写 layero.find('.layui-layer-content').css('overflow','visible')试试

dropdown用在layer中不是太好用,设置最大高度不行,始终显示所有数据,如果数据太多显示就太难看了,
输入图片说明
style: 'max-height: 300px;'

layero.find('.layui-layer-content').css('overflow','visible');

肯定有用 都测试过的

你这个测试怎么测试?我是layer是固定高度,里面的form高度是不定的,如果form的高度超过容器的高度,你用这个样式试试,form所有的控件都会显示在layer容器的外面,就像这样
输入图片说明

懂了 你这个不是没用 是不适用于,你需要转变一下了 把一行 转变 2行 以控制你的窗口高度 这样就适用了,按现有样式 估计 只能不用select,或者 尝试 lay.position (这个没试过)

针对你这个情况 可以用以下代码解决

    success:function(layero, index, that){
         //表单渲染
	 layui.form.render();
	
	 //select组件位置定位
	 function locateSelect(){
		 let selectElem= layero.find('select[lay-filter]');
		 selectElem.each((index,item)=>{
		     let selectWarpElem= layui.$(item).next();
			 
			 let top=selectWarpElem.offset().top  + selectWarpElem.height() ;
			 let left=selectWarpElem.offset().left ;
			 
			 let pos=selectWarpElem.offset();
			 let width=selectWarpElem.width();
			 let height=selectWarpElem.height();
			 
		 
			 let optionWarpElem= selectWarpElem.find('.layui-anim-upbit');
			 optionWarpElem.css({
				'position':'fixed',
				'left':left ,
				'top':top,
				'width':width,
				'min-width':'auto'
			});
		 });
	 }
	 //由于无法获知select 渲染 完成,所以多次尝试
	 for(let i=1;i<10;i++){
		setTimeout(function(){
			 locateSelect();
		},i*100);
	 }
	 
	 //滚动时隐藏,避免位置错乱
	 layero.find('.layui-layer-content').scroll(()=>{
	     layero.find('.layui-form-select').removeClass('layui-form-selected');
	 });
  }

@keqing4019 如没问题 请告知一下

这个我测试了,初始位置是对的,但是位置是绝对位置,用滚动条后,这个下拉框位置就不对了
输入图片说明

我那里边 不是有滚动后 隐藏吗 去掉了 ?

没用,你可以试试,拖动滚动条后,再select,下拉窗口位置就变了

         //滚动时隐藏,避免位置错乱 并重新定位
	 layero.find('.layui-layer-content').scroll(()=>{
	     layero.find('.layui-form-select').removeClass('layui-form-selected');
		  locateSelect();
	 });

这次完美了,解决了滚动后位置偏移问题,以及选项滚动条异常

success:function(layero, index, that){
     //表单渲染
	 layui.form.render();
	
	
	 function locateSelect(){
		 let selectElem= layero.find('select[lay-filter]');
		 selectElem.each((index,item)=>{
		     let selectWarpElem= layui.$(item).next();
			 
			 let top=selectWarpElem.offset().top  + selectWarpElem.height() ;
			 let left=selectWarpElem.offset().left ;
			 
			 let pos=selectWarpElem.offset();
			 let width=selectWarpElem.width();
			 let height=selectWarpElem.height();
			 
		 
			 let optionWarpElem= selectWarpElem.find('.layui-anim-upbit');
			 optionWarpElem.scrollTop(0);
			 optionWarpElem.css({
				'position':'fixed',
				'left':left ,
				'top':top,
				'width':width,
				'min-width':'auto'
			});
		 });
	 }
	 
	 const click=()=>{
		locateSelect();
	 };
	 
	 //由于无法获知select 渲染 完成,所以多次尝试
	 for(let i=1;i<10;i++){
		setTimeout(function(){
			 locateSelect(); 
			 layero.find('.layui-form-select').off('click',click)
			 layero.find('.layui-form-select').on('click',click)
			 
		},i*100);
	 }
	 
	
	 //滚动时隐藏,避免位置错乱
	 layero.find('.layui-layer-content').scroll(()=>{
		 layero.find('.layui-form-select').removeClass('layui-form-selected');
	 });
  }

我试试,先谢了

完美,可以了,如果layui做这方面的优化最好了,感谢大佬解决问题

那得@官方才行 不一定会给你弄

我觉得这个应该是经常能遇到的情况 @sunxiaobin

优化精简了一下 修改每次监控多个select 改成了 精准一个

  success:function(layero, index, that){
     //表单渲染
	 layui.form.render();
	
	 function locateSelect(selectWarpElem){
		 let top=selectWarpElem.offset().top  + selectWarpElem.height() ;
		 let left=selectWarpElem.offset().left;
		 
		 let pos=selectWarpElem.offset();
		 let width=selectWarpElem.width();
		 let height=selectWarpElem.height();
		 
		 let optionWarpElem= selectWarpElem.find('.layui-anim-upbit');
		 optionWarpElem.scrollTop(0).css({
			'position':'fixed',
			'left':left ,
			'top':top,
			'width':width,
			'min-width':'auto'
		});
	 }
	 
	 const click=(event)=>{
		locateSelect(layero.find(event.currentTarget));
	 };
	 
	 //由于无法获知select 渲染 完成,所以多次尝试
	 for(let i=1;i<10;i++){
		setTimeout(function(){
			 layero.find('.layui-form-select').off('click',click).on('click',click)
		},i*100);
	 }
	 
	
	 //滚动时隐藏,避免位置错乱
	 layero.find('.layui-layer-content').scroll(()=>{
		 layero.find('.layui-form-selected').removeClass('layui-form-selected');
	 });
  }

对了有个问题,这段代码在success中不会执行。我写到layer里面就可以了,你看下呢
输入图片说明

没看懂 我测试一直都是 都是layer success里的呀

我写在success里面不执行,我放到弹出层里面了

没懂 这个success 就是 layer.open 里的 success呀

success我测试不执行,你可以试试

你贴下代码 我这测试都ok

我注释了,原来是放在这个里面的
输入图片说明

我现在没懂 你用了 我写的那个代码

输入图片说明

这个就不需要了呀,不然就不会出现滚动条了,还有 你自己又写了
输入图片说明

这2句没影响,我测试过了

先打开select,然后用滚动条,下拉框就隐藏了,如果我写在success里面就没效果
输入图片说明

你的弹层是 select 是怎么渲染出来的,用的是url属性,然后再url页面里 调用 render的吗?

对的,form是用url调出来的,估计是这个问题

那你把滚动监听事件放到for循环里边

再次优化 优化滚动监听 只监听一次,滚动监听在点击后加入,避免多次监听

  success:function(layero, index, that){
     //表单渲染
	 layui.form.render();
	
	 function locateSelect(selectWarpElem){
		 let top=selectWarpElem.offset().top  + selectWarpElem.height() ;
		 let left=selectWarpElem.offset().left;
		 
		 let pos=selectWarpElem.offset();
		 let width=selectWarpElem.width();
		 let height=selectWarpElem.height();
		 
		 let optionWarpElem= selectWarpElem.find('.layui-anim-upbit');
		 optionWarpElem.scrollTop(0).css({
			'position':'fixed',
			'left':left ,
			'top':top,
			'width':width,
			'min-width':'auto'
		});
	 }
	 
	 let addScrollEvent=false;
	 const click=(event)=>{ 
		//滚动时隐藏,避免位置错乱 只监听一次
		layero.find('.layui-layer-content').one('scroll',()=>{
			layero.find('.layui-form-selected').removeClass('layui-form-selected');
		});
		locateSelect(layero.find(event.currentTarget));
	 };
	 
	 //由于无法获知select 渲染 完成,所以多次尝试
	 for(let i=1;i<10;i++){
		setTimeout(function(){
			 layero.find('.layui-form-select').off('click',click).on('click',click)
		},i*100);
	 }
  }

@keqing4019 换了另外一个思路 比较完美了 能兼容你以前碰到的问题

  success:(layero, index, that)=>{
     //表单渲染
	 layui.form.render();
	
	 const locateSelect=(selectWarpElem)=>{	 
		 let optionWarpElem= selectWarpElem.find('.layui-anim-upbit');
		
		 optionWarpElem.scrollTop(0).css({
			'position':'fixed',
			'left':selectWarpElem.offset().left ,
			'top':selectWarpElem.offset().top  + selectWarpElem.height()
		});
		
		 optionWarpElem.css({
			'width':selectWarpElem.width(),
			'min-width':'auto'
		});
	 }
	 
	 const onSelectWarpElemClick=(selectWarpElem)=>{ 
		//滚动时隐藏,避免位置错乱 只监听一次
		layero.find('.layui-layer-content').one('scroll',()=>{
			selectWarpElem.removeClass('layui-form-selected');
		});
		locateSelect(selectWarpElem);
	 };
	 
	 const deepParentFind=(el,className)=>{
		if(el.length <1){
			return null;
		}
		if(el.hasClass(className)){
			return el;
		}
		if(el.hasClass('layui-layer')){
			return null;
		}
		return deepParentFind(el.parent(),className);
	 }
	 
	 layero.on('click',(event)=>{
		let selectWarpElem=deepParentFind(layero.find(event.target),'layui-form-selected');
		if(selectWarpElem!=null){
			onSelectWarpElemClick(selectWarpElem);
		}
	 });
  }

@贤心 上述代码 比较能解决 select 被遮挡问题 可以在弹窗加个配置项selectFixed:false ,true时 在success 前加入上述代码 即可,如有更好 可以忽略此反馈

我看下,谢谢

重新获取一下 上面的代码 我发现下拉宽度不是很完善 现在修改了一下 好了

赞。 :+1:
可以放在扩展里面作为一种解决方案哈。记得之前 @sunxiaobin 也对此写了个插件。
目前暂时没有计划在 layer 的 iframe 中内置对 form select 进行这一定位支持,还是建议外部来自主实现。

好的

贤哥 弄一下吧,我这一堆iframe页面都是下拉框 全被遮挡了

要是iframe的 我感觉里边的 元素 应该不能 盖在外层上,建议iframe 里边 调用 父层的layui;例如window.top.layui.open({
//不能是iframe 类型
})

我加了他上面那个代码为啥还是陷进去了输入图片说明

输入图片说明

你的弹层是 type是2吧

我type可是1,不是2

ifarme类型弹层不适用,这个问题本质上 应该解决不了 建议 用type:1,用户ajax 获取后 在 open

是的,我是查询的地址

输入图片说明
能不能实现原生这种呢,就是原生太丑了。或者能不能修改一下lay-ignore 下的select 样式

用1呗,你就是地址,也是可以用1的

原生是浏览器效果,你用css js 是无法实现这个效果的

而且 你 用type:1实现 好处那是很多 不用担心 弹层不居中 遮挡问题 无需重复加载css js

用1 我好像一直报错输入图片说明
是这样写么

返回的整个html,然后报错
输入图片说明

哎,先不搞了,就这样了 改个原生的用用
输入图片说明

这个url 里边的内容 可能有问题 ,换成

... 简单的内容测试一下 ,里边不需要再次导入 layui js css 这类的了
贤心 添加了
 
常见
标签
贤心 添加了
 
精华
标签
贤心 任务状态待办的 修改为已完成

登录 后才可以发表评论

状态
负责人
里程碑
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
开始日期   -   截止日期
-
置顶选项
优先级
参与者(5)
8117540 my zengcheng 1622683006 92529 sentsin 1578917144
JavaScript
1
https://gitee.com/layui/layui.git
git@gitee.com:layui/layui.git
layui
layui
layui

搜索帮助

53164aa7 5694891 3bd8fe86 5694891