用js写一个小插件,解决有些浏览器不支持模态窗口的问题,并且支持嵌套

目录

之前遇到不能打开模态窗口的问题,我就自己封装了一个,拿出来给大家看看

参数说明

使用方式

页面效果:

需要注意的三个地方:

代码:

给个三连吧,兄弟们!


之前遇到不能打开模态窗口的问题,我就自己封装了一个,拿出来给大家看看

参数说明

/*
		url:要打开的页面
		option:
		 	    title --展示的标题
                height -- 消息窗口高度 可以填400或者400px,缺省300px
                width  --消息窗口宽度 可以填400或者400px,缺省300px
                confimCall 打开的模态窗口中按钮“确定”对应的函数名,当模态窗口的页面点击确定 就会调用那个函数       
                confimCallback --按钮“确定” 可以回调当前配置的函数,需在confimCall写好函数 回调
                cancelCall --打开的模态窗口中按钮“取消”对应的函数名,当模态窗口的页面点击取消 就会调用那个函数 
                cancelCallback -- 按钮“取消” 可以回调当前页面,需在cancelCall写好函数 回调
                parent -- 如果想在当前打开的modal页面,再次打开新的模态页面,需要加上这个属性  如下这么传( parent:window.parent )
	*/		 

使用方式

页面效果:

需要注意的三个地方:

1.因为用了iframe,所以涉及跨域的问题,如果像现在这样去调用,点击“确定”“取消”的时候,会报错:

   Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.

  因为是用的本地服务 :file:///打开会报这个错误,需要部署起来,比如tomcat。

2.confimCallback的配置方法

  首先配置好调用函数

在新模态页面上,对ev_confirm 函数进行处理

3.如果想在当前打开的modal页面,再次打开新的模态页面,需要加上这个属性  如下这么传( parent:window.parent ),之前做的一个例子就是这样写的。

代码:

test.html

 
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=GBK">
        <style>
        *{
        	margin:0;padding:0;
        	text-align:center;
        }
        </style>
        </head>
        <body>
        	<h1>这是一个页面</h1>
        	<button onclick='openModal()'>打开新modal</button>
        </body>
        
<script>
		function openModal(){
			 var url='./test1.html';
			 showModal(url,{width:"450",height:"400px",title:'这是新的模态窗口',confimCall:'ev_confirm',confimCallback:function(){
			 	//确定的回调函数
			 	console.log('回调执行')
			 }});
		}

	/*
		url:要打开的页面
		option:
		 	    title --展示的标题
                height -- 消息窗口高度 可以填400或者400px,缺省300px
                width  --消息窗口宽度 可以填400或者400px,缺省300px
                confimCall 打开的模态窗口中按钮“确定”对应的函数名,当模态窗口的页面点击确定 就会调用那个函数       
                confimCallback --按钮“确定” 可以回调当前配置的函数,需在confimCall写好函数 回调
                cancelCall --打开的模态窗口中按钮“取消”对应的函数名,当模态窗口的页面点击取消 就会调用那个函数 
                cancelCallback -- 按钮“取消” 可以回调当前页面,需在cancelCall写好函数 回调
                parent -- 如果想在当前打开的modal页面,再次打开新的模态页面,需要加上这个属性  如下这么传( parent:window.parent )
	*/		 
    function showModal(url,option){
     	 var html='',modalDiv,marginLeft,title,confimCall,cancelCall,confimCallback,cancelCallback,width='300px',height='300px';
     	 var option=option||{};
     	 
     	 // 兼容多层弹出页面
     	 var parent = option.parent||window;
     	 var realDocument =parent.document;
     	 var realEl = realDocument.body;
     	 
     	 title=option.title||'窗口';
     	 option.confimCall && (confimCall = option.confimCall );
     	 option.confimCallback && (confimCallback = option.confimCallback );
	  	 option.cancelCall && (cancelCall = option.cancelCall );
	  	 option.cancelCallback && (cancelCallback = option.cancelCallback );
	  	 option.width && (width = option.width );
	  	 option.height && (height = option.height );
	  	 
	  	 marginLeft=-parseInt(width)/2+'px',width=parseInt(width)+'px',height=parseInt(height)+'px';
	  	 
     	 
     	 var id = Math.random().toString().replace('.','');
     	 var modalDiv = realDocument.getElementById("content_div_"+id);	
     	 if(modalDiv){
     	 	realEl.removeChild(modalDiv);
     	 	modalDiv=null;
     	 }
     	 
     	 var frameId = "IFRAME_"+id;
     	 
		 modalDiv = realDocument.createElement("div");
		 modalDiv.id="content_div_"+id;	
		 modalDiv.style.position = "absolute";		
		 
	 	 modalDiv.style.top="0px";
	     modalDiv.style.margin ="0";
	     modalDiv.style.padding ="0";
	     html = '<div id="content_bg_'+id+'" style="Z-INDEX: 1; BACKGROUND: #ccc;LEFT: 0px; POSITION: absolute; TOP: 0px;FILTER: alpha(opacity=100);opacity: 1">';
	     html +='<div id="content_child_div_'+id +'" style="background:#908c8cd9;width:'+width+';height:'+height+';z-index:5;left:50%;margin-left:'+(marginLeft)+';position:absolute;border-radius:8px;">';
		 
		 if(title){
		 	 html +='<div style="border-bottom: 1px dashed rgb(221, 221, 221);height:87%;width: 100%;">';
		 	 html +='<div><span style="display: block;font-size: 14px;padding: 8px 15px;background-color: lightgoldenrodyellow;border-radius: 8px 8px 0px 0px;border-bottom: 2px solid rgb(48, 153, 220);font-weight: bold;">' + title + '</span>';
			 html +='<span id="msg_ico_'+id+'" style="display: block;position: absolute;right: 10px;top: 9px;border: 1px solid gray;width: 18px;height: 18px;text-align: center;line-height: 15px;cursor: pointer;border-radius: 12px;">x</span></div>';
		 }
		 html +='<div style="margin-left: 1px;margin-right: 1px;overflow: hidden;height: 87%;">';
		 html += "<iframe id='"+frameId+"' src='"+url+"' style='width: 100%; height: 100%;'></iframe>";		
		 html +='</div></div>';
		 
	 	 html +="<div style='margin:3px;text-align: center;'>"
			  +"<input id='confirmEventDiv_"+id+"' type='button' value='确定' style='width:85px;height:30px;color:white;border:none;cursor:pointer;background-color:rgb(187, 28, 28);letter-spacing: 6px;'>"
			  +"<input id='closeEventDiv_"+id+"' type='button' value='取消' style='width:85px;height:30px;color:white;border:none;cursor:pointer;background-color:slategray;margin-left: 20px;letter-spacing: 6px;'>"
		      +"</div>";
		 
		 html +='</div></div>';
		 
		 modalDiv.innerHTML	= html ;
		 realEl.appendChild(modalDiv);
		 
    	 var content_bg = realDocument.getElementById("content_bg_"+id);
			 content_bg.style.width =realEl.clientWidth+"px";
			 content_bg.style.height=getToastHeight()+'px';
			 content_bg.childNodes[0].style.top = (parent.scrollY||realDocument.documentElement.scrollTop) + parent.screen.availHeight * 0.15 +'px';
    
    	
   		var confirmEventDiv = realDocument.getElementById("confirmEventDiv_"+id);
	 	var closeEventDiv = realDocument.getElementById("closeEventDiv_"+id);
	 	var msg_ico = realDocument.getElementById("msg_ico_"+id);
	 	if(document.addEventListener){
	 		confirmEventDiv && confirmEventDiv.addEventListener('click',confirmDiv);
	 		closeEventDiv && closeEventDiv.addEventListener('click',closeDiv);
	 		msg_ico && msg_ico.addEventListener('click',closeDiv);
	 	}else{
	 		confirmEventDiv && confirmEventDiv.attachEvent('onclick',confirmDiv);
	 		closeEventDiv && closeEventDiv.attachEvent('onclick',closeDiv);
	 		msg_ico && msg_ico.attachEvent('onclick',closeDiv);
	 	}
	
		 var childIframe = realDocument.getElementById(frameId);
		 var childWindow = childIframe.contentWindow;
		 function confirmDiv(){
		 	if(!confimCall) {//直接关闭
		 		modalDiv.style.display="none";
		 		return ;
		 	} 
			if(doCallback(childWindow[confimCall],confimCallback)){
				modalDiv.style.display="none";
			}
		 }
		 
		 function closeDiv(){//关闭是不执行回调函数的
		 	if(!cancelCall) {//直接关闭
		 		modalDiv.style.display="none";
		 		return ;
		 	} 
		 	if(doCallback(childWindow[cancelCall],cancelCallback)){
		 		modalDiv.style.display="none";
		 	}
		 }
		 
		 function doCallback(fn,callback){
			if(fn && _.isFunction(fn)){
				var res = fn(callback);
				if(!res && String(res)=='false'){
					return false;
				}
			}
			return true;
		 }
    	function getToastHeight(){
		 	return parent.screen.availHeight > realEl.clientHeight ? parent.screen.availHeight : realEl.clientHeight;
		 }
    }
</script>
</html>

test1.html

 
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=GBK">
        <style>
        *{
        	margin:0;padding:0;
        }
        </style>
        </head>
        <body>	
        	<h1>这是一个打开的modal页面</h1>
        </body>
        <script>
        //点击确定点击的函数 confimCall:'ev_confirm' 配置的
         function ev_confirm(cb){//形参cb就是confimCallback 配置的回调函数
         	console.log('新模态页面点击');
         	cb();//执行完确定会回调此函数
         }
        </script>
</html>

给个三连吧,兄弟们!

猜你喜欢

转载自blog.csdn.net/dkm123456/article/details/112493337