最近做的项目,两个弹出窗口的方式都接触到了,总结一下使用的经验。
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>
这样一来可以实现从模式窗口向父窗口传递值的作用,
这个returnValue除了可以是布尔值,整型值等以外还可以是个js数组,用来传递大量数据。
showModalDialog,是模态窗口,始终获得焦点,但弹出的窗体不能刷新,此弹出的窗口里操作button,要想不弹出新窗口,需在
弹出的窗口中在<head>和</head>之间加<base target="_self">。
(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操作,我是参考点击打开链接写的。
以上两种对子窗口进行控制的方式介绍到这里。