最近做的项目,两个弹出窗口的方式都接触到了,总结一下使用的经验。
1.什么是模态窗口:
模态窗口就是只有你当前弹出的对话框为有效,其他父窗体之类都无效,像你有时候鼠标点上去都没有反应。感觉用在强迫用户在子窗口完成一个操作时候,使用模态窗口比较合适。例如,我在做审批拒绝时候,需要用户输入审核内容,弹出一个模态窗口,强制用户输入内容以后,才可以返回父窗口进行其他操作。
window.showModalDialog使用手册
基本介绍:
showModalDialog() (IE 4+ 支持)
showModelessDialog() (IE 5+ 支持)
window.showModalDialog()方法用来创建一个显示HTML内容的模态对话框。
window.showModelessDialog()方法用来创建一个显示HTML内容的非模态对话框。
使用方法:
vReturnValue = window.showModalDialog(sURL [, vArguments] [,sFeatures])
vReturnValue = window.showModelessDialog(sURL [, vArguments] [,sFeatures])
参数说明:
sURL--
必选参数,类型:字符串。用来指定对话框要显示的文档的URL。
vArguments--
可选参数,类型:变体。用来向对话框传递参数。传递的参数类型不限,包括数组等。对话框通过window.dialogArguments来取得传递进来的参数。
sFeatures--
可选参数,类型:字符串。用来描述对话框的外观等信息,可以使用以下的一个或几个,用分号“;”隔开。
1.dialogHeight :对话框高度,不小于100px,IE4中dialogHeight 和 dialogWidth 默认的单位是em,而IE5中是px,为方便其见,在定义modal方式的对话框时,用px做单位。
2.dialogWidth: 对话框宽度。
3.dialogLeft: 离屏幕左的距离。
4.dialogTop: 离屏幕上的距离。
5.center: {yes | no | 1 | 0 }:窗口是否居中,默认yes,但仍可以指定高度和宽度。
6.help: {yes | no | 1 | 0 }:是否显示帮助按钮,默认yes。
7.resizable: {yes | no | 1 | 0 } [IE5+]:是否可被改变大小。默认no。
8.status: {yes | no | 1 | 0 } [IE5+]:是否显示状态栏。默认为yes[ Modeless]或no[Modal]。
9.scroll:{ yes | no | 1 | 0 | on | off }:指明对话框是否显示滚动条。默认为yes。
下面几个属性是用在HTA中的,在一般的网页中一般不使用。
10.dialogHide:{ yes | no | 1 | 0 | on | off }:在打印或者打印预览时对话框是否隐藏。默认为no。
11.edge:{ sunken | raised }:指明对话框的边框样式。默认为raised。
12.unadorned:{ yes | no | 1 | 0 | on | off }:默认为no。
2.open方法弹出的窗口:
和模态窗口相反,可以在子窗口弹出的同时,操作父窗口。
示例:
<SCRIPT>
<!--
window.open ('page.html','newwindow','height=100,width=400,top=0,left=0,toolbar=no,menubar=no,scrollbars=no, resizable=no,location=no, status=no')
//写成一行
-->
</SCRIPT>
脚本运行后,page.html将在新窗体newwindow中打开,宽为100,高为400,距屏顶0象素,屏左0象素,无工具条,无菜单条,无滚动条,不可调整大小,无地址栏,无状态栏。
请对照。
上例中涉及的为常用的几个参数,除此以外还有很多其他参数,请见四。
四、各项参数
其中yes/no也可使用1/0;pixel value为具体的数值,单位象素。
参数 | 取值范围 | 说明
| |
alwaysLowered | yes/no | 指定窗口隐藏在所有窗口之后
alwaysRaised | yes/no | 指定窗口悬浮在所有窗口之上
depended | yes/no | 是否和父窗口同时关闭
directories | yes/no | Nav2和3的目录栏是否可见
height | pixel value | 窗口高度
hotkeys | yes/no | 在没菜单栏的窗口中设安全退出热键
innerHeight | pixel value | 窗口中文档的像素高度
innerWidth | pixel value | 窗口中文档的像素宽度
location | yes/no | 位置栏是否可见
menubar | yes/no | 菜单栏是否可见
outerHeight | pixel value | 设定窗口(包括装饰边框)的像素高度
outerWidth | pixel value | 设定窗口(包括装饰边框)的像素宽度
resizable | yes/no | 窗口大小是否可调整
screenX | pixel value | 窗口距屏幕左边界的像素长度
screenY | pixel value | 窗口距屏幕上边界的像素长度
scrollbars | yes/no | 窗口是否可有滚动栏
titlebar | yes/no | 窗口题目栏是否可见
toolbar | yes/no | 窗口工具栏是否可见
Width | pixel value | 窗口的像素宽度
z-look | yes/no | 窗口被激活后是否浮在其它窗口之上
3.两种方式的传值:
(1)模态窗口:
returnValue是javascript中html的window对象的属性,目的是返回窗口值,当用window.showModalDialog函数打开一个IE的模式窗口(模式窗口就是子窗口,打开后不能操作父窗口,只能等模式窗口关闭时才能操作)时,用于返回窗口的值,下面举个例子:
------------------------------------------------------------------------------
//father.html <HTML> <HEAD> <META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0"> <TITLE></TITLE> <script language="javascript"> function showmodal(){ var ret = window.showModalDialog("child.html",null,"dialogWidth:350px;dialogHeight:350px;help:no;status:no"); if (ret){alert('子窗口返回真!'); }else{ alert('子窗口返回假!'); } } </script> </HEAD> <BODY> <INPUT id=button1 type=button value=Button name=button1 onclick="showmodal();"> </BODY> </HTML>------------------------------------------------------------------------------
//child.html <HTML> <HEAD> <META NAME="GENERATOR" Content="Microsoft Visual Studio 6.0"> <TITLE></TITLE> <script language="javascript"> function trans(tag){ if (tag==0){ window.returnValue=false; } else{ window.returnValue =true; } window.close(); } </script> </HEAD> <BODY> <INPUT id=button1 type=button value="返回真" name=button1 onclick="trans(1)"> <INPUT id=button2 type=button value="返回假" name=button2 onclick="trans(0)"> </BODY> </HTML>
(2)open的窗口:
可以通过window.opener,获得父窗口对象,一般通过dom操作进行传值(我是这样做的,比如可以在父窗口放个hidden的控件,通过dom来进行操作),通过一个简单的例子,DOM进行操作,以下例子,实现功能是子窗口有一排复选框,当选中复选框,父窗口中的表格就会自动添加一行,当取消复选框时候,父窗口中的相应表格行就会删除掉。
父窗口的JS代码:按钮触发该方法
function getProblemWindow(){ window.open("getProblemWindow.action","请选择添加的问题","location=no,width=950,height=350," +"toolbar=no,scrollbars=yes,menubar=no,screenX=100,screenY=100"); };
子窗口的HTML代码:
<%@ page language="java" contentType="text/html; charset=utf-8"%> <%@ include file="/WEB-INF/include/taglib.jsp"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <%@ include file="/WEB-INF/include/head.jsp"%> <script> var arrProblemId = new Array();//数组中存放为选中的problem的Id var arrCount = new Array();//用于设置获取父窗口中,第几道题,当作一个栈使用 var parentWindow = window.opener.document; //var countProblem = parentWindow.getElementById("countProblem").getAttribute("value");//获取父窗口的一个hidden,其记录题目数量信息 //var count=parseInt(countProblem);//统计题目数量 function query(){ document.forms(0).action="getProblemWindow.action"; document.forms(0).submit(); } function update(id){ window.location.href="view.action?path=edit&entity.id="+id; } function deleted(id){ window.location.href="view.action?path=delete&entity.id="+id; } function view(id){ window.location.href="view.action?path=view&entity.id="+id; } function census(problemId,checkbox){ var form1 = parentWindow.getElementById("form1"); var table1 = parentWindow.getElementById("paper1"); //判断,选中的单选框将其ID加入数组,被取消点击的删除数组中的内容 if(checkbox.checked==true){ //count++; arrProblemId.push(problemId); /* arrCount.push(count); if(arrCount.length>=2){ arrCount.reverse(); } */ var newTr=parentWindow.createElement("tr"); var newTd=parentWindow.createElement("td"); var newTd2=parentWindow.createElement("td"); var newBtn=parentWindow.createElement("input"); newBtn.setAttribute("type","button"); newBtn.setAttribute("value","删除该题"); newBtn.setAttribute("name","deleteBtn"+problemId); newBtn.setAttribute("onclick","deleteProblem2(\""+problemId+"\",this);"); //父窗口创建一个hidden var id = parentWindow.createElement("input"); id.setAttribute("type","hidden"); id.setAttribute("value",problemId); id.setAttribute("name","problemIds");//名称相同,返回给struts2自动封装相应名称的List对象 //newTd.innerHTML="第"+arrCount.pop()+"题"; //arrCount.length=0; //获取题目名称 var content = checkbox.getAttribute("content"); //设置tr的id newTr.setAttribute("id","tr"+problemId); newTr.setAttribute("name","tr"+problemId); //newTd.innerHTML=problemId; newTd.appendChild(id); newTd.appendChild(newBtn); newTd2.innerHTML=content; newTr.appendChild(newTd); newTr.appendChild(newTd2); table1.appendChild(newTr); }else{ //count--; var location; for(var i=0;i<arrProblemId.length;i++){ if(arrProblemId[i]==problemId){ arrProblemId.splice(i,1); location = i;//获得位置下标 } } //arrCount.push(location+1);//将被删除的计数题号入栈 //寻找id为problemId的tr,并删除 var newTr = parentWindow.getElementById("tr"+problemId); table1.removeChild(newTr); } } </script> </head> <body onunload="destroy();"> <form name="from1" method="post" action="list.action" > <table width="90%" cellpadding="0" cellspacing="0"> <tr> <td>创建</td> </tr> <tr> <td> <fieldset> <legend>查询条件</legend> <table width="100%"> <tr> <th>名称</th> <td> <s:textfield name="problem.content"/> </td> <th>问题类型</th> <td> <s:select list="#{'-1':'全部','0':'单选题','1':'多选题','2':'判断题','3':'简答题'}" name="problem.type"></s:select> </td> <th>时间</th> <td> <input type="text" size="22" name="problem.q_beginTime" onfocus="WdatePicker({readOnly:true})" class="Wdate" value="<s:date name="problem.q_beginTime" format="yyyy-MM-dd"/>" /> - <input type="text" size="22" name="problem.q_endTime" onfocus="WdatePicker({readOnly:true,dateFmt:'yyyy-MM-dd HH:mm:ss'})" class="Wdate" value="<s:date name="problem.q_endTime" format="yyyy-MM-dd HH:mm:ss"/>" /> </td> <th>创建人</th> <td> <s:textfield name="problem.createUser"/> </td> <th>问题状态</th> <td> <s:select list="#{'-1':'全部','0':'未使用','1':'已使用'}" name="problem.state"></s:select> </td> </tr> </table> </fieldset> </td> </tr> <tr> <td align="right"> <input type="button" name="button1" value="查询" onclick="query();"/> </td> </tr> <tr> <td> <table cellpadding="0" cellspacing="0" border="1" width="100%" > <tr> <th width="5%">选择</th> <th width="5%">序号</th> <th width="50%">问题名称</th> <th width="10%">题型</th> <th width="10%">问题状态</th> <th width="10%">创建人</th> <th width="10%">创建时间</th> </tr> <s:iterator value="pageData.list" var="problem" status="tableId"> <tr> <td> <s:checkbox name="problemIds" onclick="census(\"%{#problem.id}\",this);" content="%{#problem.content}" /> </td> <td> <s:property value="#tableId.index+1"/> </td> <td> <s:property value="#problem.content" /> </td> <td> <s:if test="#problem.type==0">单选题</s:if> <s:if test="#problem.type==1">多选题</s:if> <s:if test="#problem.type==2">判断题</s:if> <s:if test="#problem.type==3">简答题</s:if> </td> <td> <s:if test="#problem.state==0">未使用</s:if> <s:if test="#problem.state==1">已使用</s:if> </td> <td> <s:property value="#problem.createUser" /> </td> <td> <s:date name="#problem.createTm" format="yyyy-MM-dd HH:mm:ss"/> </td> </tr> </s:iterator> </table> </td> </tr> <tr> <td> <capinfo:page action="getProblemWindow.action" width="800" pageData="${pageData}" /> </td> </tr> </table> </form> </body> </html>
关于dom操作,我是参考点击打开链接写的。
以上两种对子窗口进行控制的方式介绍到这里。