设计网站交互时,尽量不要有太多的弹出框,这样对用户来说很突兀,打开多个弹出窗口后,都不知道哪一个是哪一个,有的是模式对话框,弹出一个后,主窗口不能正常操作,浏览器也不能关闭,必须关掉该对话框;技术上要考虑主窗口和子窗口的通讯,数据传递,刷新子窗口时也会遇到另开页面的情况;一般的,浏览网页时,以下情况可能会用到弹出框:
1、小的操作,要求简单的交互,比如输入用户名、身份二次验证;
2、上传附件,支持拖曳操作时,把上传功能放在一个复杂页面上或直接新开一个页面操作完成后在返回倒不如直接弹出一个对话框;
3、操作上有逻辑先后要求的,必须登录成功才可以跳转到另一个页面,比如网易云阅读主页可以正常浏览,但是要查看个人订阅的资讯和专题列表就必须登录;
在网页上实现弹出框操作,目前用过的有这几种方法:jquery showdialog() 、window.open()、window.showModalDialog()。前几天工作上遇到一个需求:在主窗口A上点击按钮弹出窗口,从gridview中选择人员,返回选中人员的id信息并关闭当前窗口;把返回的值保存在隐藏域中,方便主页面使用,有以下问题:
1、从主窗口A跳转到子窗口怎么接收返回的值?
2、js操作gridview,收集到选中的值
3、怎么处理数据格式
思路:
页面间传值有不少方法,可以通过url地址发送get请求,或隐藏域post表单等;在这使用window.showModalDialog()模式对话框。主要原因:可以把主窗口中的对象传递到子窗口,子窗口中的数据可以通过window.returnValue方式返回。如下一个例子:
root=window.showModalDialog('SelectPersons.aspx',root,'dialogWidth=630px;dialogHeight=520px;center=yes;scroll:yes;')
有三个参数,后面两个是可选参数,指定要跳转的url地址,root是传递到子窗口的对象;第三个参数是设置弹出框的状态。
gridview最终输出到html页上是一个表格,通过js获取到input集合,从中筛选出checkbox标签,可以取到选中的值。
操作数据可以使用数组、拼接一个字符串、xmlDocument对象等方式。
A窗口aspx页
<% @ Page Language="C#" AutoEventWireup="true" CodeBehind="TestModalWindow.aspx.cs"
Inherits="Test.TestModalWindow" %>
<!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 runat="server">
<title></ title>
<script type="text/javascript">
/* 人员选择 */
function SelectPerson() {
//xml结构:如后台说明
var obj = document.getElementById('hidPersonInfo' );
var xmlData = obj.value;
var root = null ;
if (xmlData != "" ) {
var xmldoc = new ActiveXObject("Microsoft.XMLDOM");
xmldoc.loadXML(xmlData);
root = xmldoc.documentElement; //返回根节点
}
root = window.showModalDialog( 'SelectPersons.aspx', root, 'dialogWidth=630px;dialogHeight=520px;center=yes;scroll:yes;' );
if (root != null ) {
var strValue = "" ;
var guidValue = "" ;
obj.value = root.xml;
//行循环
for (var k = 0; k < root.childNodes.length; k++) {
//行节点
var rowNode = root.childNodes.item(k);
//列循环
for (var i = 0; i < rowNode.childNodes.length; i++) {
//列节点
var currNode = rowNode.childNodes.item(i);
//列名
var strName = currNode.getAttribute("Name" ).toLowerCase();
if (strName == "name" ) {
strValue += currNode.getAttribute( "Value") + "," ;
}
else if (strName == "personguid") {
guidValue += currNode.getAttribute( "Value") + "," ;
}
}
}
if (strValue.length > 0) {
strValue = strValue.substring(0, strValue.length - 1);
}
if (guidValue.length > 0) {
guidValue = guidValue.substring(0, guidValue.length - 1);
}
document.getElementById( "hidPersonInfo").value = guidValue;
document.getElementById( "txtPersonsName").value = strValue;
}
}
/* 清空已选择人员 */
function ClearPerson() {
document.getElementById( 'hidPersonInfo').value = "" ;
document.getElementById( "txtPersonsName").value = "" ;
}
function ShowVal() {
var val = document.getElementById('hidPersonInfo' ).value;
alert( "选择姓名对应的guid:" + val);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
下面是测试: <br />
姓名: <input type="text" id="txtPersonsName" name="txtPersonsName" />
<input type="button" value="人员选择" οnclick="SelectPerson()" />
<input type="hidden" runat="server" id="hidPersonInfo" name="hidPersonInfo" />
<input type="button" value="显示选择的guid" οnclick="ShowVal()" />
</div>
</form>
</body>
</html>
子窗口页
<% @ Page Language="C#" AutoEventWireup="true" CodeBehind ="SelectPersons.aspx.cs"
Inherits ="Test.SelectPersons" %>
<! 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 runat ="server">
< title></ title >
< script type ="text/javascript">
//xml结构:如后台说明
var root = null ; //xml节点的根节点
var xmldoc = null ;
window.onload = function () {
root = window.dialogArguments; //接收传递过来的参数
//加载已被选择的信息
if (xmldoc != null ) {
xmldoc = root.ownerDocument; //返回文档对象
}
else {
xmldoc = new ActiveXObject("Microsoft.XMLDOM" );
}
//将已存在的选择信息显示到顶部
var strValue = "" ;
if (root != null ) {
//行循环
for (var k = 0; k < root.childNodes.length; k++) {
//行节点
var rowNode = root.childNodes.item(k);
//列循环
for (var i = 0; i < rowNode.childNodes.length; i++) {
//列节点
var currNode = rowNode.childNodes.item(i);
//将姓名内容取出来,进行组合显示
var strName = currNode.getAttribute("Name" ).toLowerCase();
if (strName == "name" ) {
strValue += currNode.getAttribute( "Value" ) + "," ;
}
}
}
if (strValue.length > 0) {
strValue = strValue.substring(0, strValue.length - 1);
}
}
document.getElementById( "SelectedTitle" ).innerText = "已选择:" + strValue;
}
/* 确认选择并关闭 */
function okClick() {
//判断是否已存在节点信息,不存在创建根节点
if (root == null ) {
//创建根节点****************************************************
root = xmldoc.createElement( "EnterpriseInfo" );
}
//DataGrid列表数据选择[加载到xml节点中]
var nCount = document.getElementById("dgrdHortationList" );
var chks = nCount.getElementsByTagName( 'input');
for (var i = 0; i < chks.length; i++) {
if (chks[i].type = 'checkbox' ) {
if (chks[i].checked) {
//将PersonGUID,PersonTypeGUID,Name加载到xml节点中
var temp = chks[i].value;
var arry = temp.split('|' );
//检测本企业是否已选过,是的话就不允许再添加
var personGUID = arry[0];
var node = root.selectSingleNode("//Column[@Name='PersonGUID' and @Value='" + personGUID + "']" );
if (node == null ) {
//创建行节点****************************************************
var rowNode = xmldoc.createElement("Row" );
//添加列节点****************************************************
rowNode = GetColumnNode(xmldoc, rowNode, "PersonGUID" , personGUID); //人员GUID
rowNode = GetColumnNode(xmldoc, rowNode, "Name" , arry[1]); //人员姓名
//将行节点追加到根节点中****************************************
root.appendChild(rowNode);
}
}
}
}
//将选择的信息返回
chooseItem(root);
}
/* 返回已选择的企业 */
function chooseItem(item) {
window.returnValue = item;
window.close();
}
/* 组合有值的字段到xml结构中 */
function GetColumnNode(xmldoc, rowNode, columnName, columnValue) {
//只组合有值的字段到xml结构中
if (columnValue != "" ) {
var columnNode = xmldoc.createElement( "Column");
//列对应字段名称
var att = xmldoc.createAttribute("Name" );
att.value = columnName;
columnNode.setAttributeNode(att);
//列对应字段值
att = xmldoc.createAttribute( "Value" );
att.value = columnValue;
columnNode.setAttributeNode(att);
rowNode.appendChild(columnNode);
}
return rowNode;
}
</ script>
</ head>
< body>
< form id ="form1" runat ="server">
< div>
< input type ="hidden" id ="SelectedTitle" name ="SelectedTitle" />
< input type ="button" value ="确定选择并关闭" onclick ="okClick()" />
< asp: DataGrid ID ="dgrdHortationList" runat ="server" AutoGenerateColumns ="False" BorderWidth ="0"
CellPadding ="0" CellSpacing ="0">
< Columns>
< asp: TemplateColumn >
< ItemTemplate>
< input type ="checkbox" value ="<% # Eval("guid") %>| <% # Eval("name") %>" />
</ ItemTemplate>
</ asp: TemplateColumn >
< asp: TemplateColumn HeaderText ="姓名">
< ItemStyle></ ItemStyle >
< ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "name" )%>
</ ItemTemplate>
</ asp: TemplateColumn >
< asp: TemplateColumn HeaderText ="性别">
< ItemTemplate>
<%# Eval( "sex") %>
</ ItemTemplate>
</ asp: TemplateColumn >
< asp: TemplateColumn HeaderText ="工作单位">
< ItemStyle></ ItemStyle >
< ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "workunit" )%>
</ ItemTemplate>
</ asp: TemplateColumn >
</ Columns>
</ asp: DataGrid >
</ div>
</ form>
</ body>
</ html>
存在的问题:
1、var xmldoc = new ActiveXObject("Microsoft.XMLDOM"); 实例化xmlDoc对象时,不能很好兼容chrome 、ff等主流浏览器,网上有方法和代码,测试还是不行,没找到问题原因;
2、在子窗口如有其他操作,如有查询、翻页、跳转都会新开页面,处理方法可以直接在header头部中间指定整个页面的打开方式,如:
<base target="_self" />