window.open和window.showModalDialog的异同与子父窗口之间值的传递

window.open和window.showModalDialog的异同与子父窗口之间值的传递
大家对于window.open都比较了解,window.open确实可以满足我们绝大部分的需求,但当你不可避免的要使用window.showModalDialog时,你可能就对它知之甚少了。

首先来谈谈他们的异同
1、相同点:这两种方式都可以打开新窗口。
2、前者是非阻塞式,也可以说非模态窗口。而后者是阻塞式模态窗口。阻塞或者模态窗口,只有你把当前窗口关闭后,才能去操作父亲窗口。所以ModalDialog也称为HTML文档的模式对话框。
3、传值方式和参数不同,这个在下文会详细介绍。

说完window.open和window.showModalDialog的异同,下面就该谈谈它们的用法了。
1、window.open(url, name, size);
url:要打开新窗口的地址url;
name:打开新窗口的名称,若名称相同,则之后打开的窗口会覆盖之前的窗口;若不相同,则会再打开一个新窗口;
size:长宽等参数(常用);
例:window.open("sample.do","newWindow","height=200,width=400");

2、 var  retunrnVaule  = window.showModalDialog(url, arguments, size);
url:要打开新窗口的地址url;
arguments:传到子窗口的参数,可以传值,但一般直接写window,代表将整个父窗口都传到子窗口中,那父窗口所有的值都能在子窗口中取到 了;
size:长宽等参数(常用);
var retunrnVaule  = window.showModalDialog("modal.do",window,"dialogWidth=200px;dialogHeight=100px");

然后我们再来说说它们父子窗口间的传值是如何完成的吧。
1、 window.open:
   父窗口向子窗口传值,window.open的父窗口向子窗口传值可以通过url直接来传递到后台,在后台再将要返回的值塞到子窗口。这就完成了父 窗口向子窗口值的传递。
       例: window.open("sample.do?value='value'","newWindow","height=200,width=400");
    还有一种不为人知的方式,因为子窗口可以通过window.parent来获取父窗口,所以可以直接在子窗口调用父窗口的标签来获 取某标签的值,同样可以在子窗口获取父窗口的值。
    例:window.parent.$("#input").val();
   子窗口向父窗口传值,window.open子窗口向父窗口传值的方式,我一般都会使用用window.parent来调用父窗口方法,将想要传递的值放在参 数中,执行父页面方法的同时,值也传递过去了,这就实现了子窗口向父窗口的传值。
    例:window.parent.setValue(value1, value2);

2、 window.showModalDialog:
   父窗口向子窗口传值,window.showModalDialog的父窗口向子窗口传值前文已经说过在参数中直接写上window就可以将整个父页面给传到子窗 。子窗口可以通过window.dialogArguments获取父窗口所有的方法和标签内容。
    例:window.dialogArguments.$("#input").val();
   子窗口向父窗口传值,window.showModalDialog的子窗口向父窗口传值有两种,
    第一种方式和window.open的传值方式类似,个人比较推荐这种 方法,通过window.dialogArguments来调用父页面方法,并通过方法的参数来传值
    不过这里有一点要提醒大家注意的, window.dialogArguments有些浏览器不支持(如:360浏览器兼容模式),那么怎么办呢。
    通过实验我发现,ie只认识window.dialogArguments ,而其他浏览器有的不认识window.dialogArguments却可以通过window.opener来调用父页面方法,这时候我们可以先判断是否是ie浏览器,把 这个只认识window.dialogArguments的就用window.dialogArguments来调用父页面方法,而其他浏览器都认识window.opener,所以可以使用 window.opener来调用父页面方法。
    例:function parentFunc(value1, value2){
       var isIE = false;  
       //这行代码可以判断是否是ie浏览器
       if (window.navigator.userAgent.indexOf("Trident") != -1){  
           isIE= true;  
       }  
       //通过是否是ie浏览器来分别进行父页面方法的调用
       if(isIE){ 
        window.dialogArguments.func(value1, value2);
       }else{  
           window.opener.func(value1, value2);
       }
}
    另一种方法比较笨重,不够灵活,但代码量比较少,更加简洁,就是使用window.showModalDialog自身方法所带的returnValue来进行子页面向 父页面的传值。
    父页面定义一个变量来接收window.showModalDialog的返回值,子页面通过window.returnValue(固定写法)来将值返回给父 页面,父页面通过定义的变量接收到值后可以继续执行下面的js代码。
     例:父页面:var returnValue = window.showModalDialog("child.do",window,"dialogWidth:350px;dialogHeight:350px");
alert(returnValue);
    子页面:window.returnValue = “returnValue”;
    执行结果:弹出“returnValue”。

    这里也可以看出window.open和window.showModalDialog的不同之处, window.showModalDialog打开新窗口后无法操作父页面,所以js可以停住等到子页面关闭时再继续执行剩下的js,而window.open打开新窗口后 还可以对父页面进行操作,所以也就没办法拥有这个功能了。
    
    这种方法也可以成功的将值从子页面传递到父页面。但本人亲测后发现谷歌浏览器竟然不兼容,瞬间感觉身体被掏空。不过在经历过不断的尝 试之后,机智过人的我还是找到了一个小方法。
    我发现谷歌浏览器是认window.opener的,所以我们可以在子页面给父页面的returnValue赋 值,然后再在父页面通过window.returnValue就可以取得子页面传过来的值。
优化后代码为:
    父页面:var returnValue = window.showModalDialog("child.do",window,"dialogWidth:350px;dialogHeight:350px");
    //for chrome 
    if (returnValue == undefined) {
        returnValue = window.returnValue;
    }
    alert(returnValue);
    子页面:window.returnValue = "returnValue";
    //for chrome
    if(window.opener){
       window.opener.returnValue = "returnValue";
    }

    这样就可以完美的解决谷歌浏览器不兼容的问题了,是不是很开心呢。
PS:在js中,returnValue == undefined 和 typeof(returnValue) == "undefined" 的效果是一样的。都可以判断变量returnValue是否未定义。


若你还有其他方法解决这个问题,欢迎在下方留下你的方式,大家一起讨论,一起进步,做一只有梦想的网虫!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值