js 页面间的通信

王朝学院·作者佚名  2016-05-22
窄屏简体版  字體: 小  |  中  |  大  |  超大  

js 页面间的通信看了一下公司原来的代码,原页面Ajax post返回一个页面完整的HTML,然后再打开一个新页面并输出ajax返回的所有代码到新页面上,在新页面上以表单提交的形式实现重定向。

任凭我想了半天也没想出来,怎么样不借助node就直接用js生成新页面并输入数据到新页面上以初始化。然后百度,必应搜索(公司电脑安全设置不能用greenshadowFQ,郁闷!),关键词不对,没搜到想要的结果。趁着面试,问了一下考官,关键词是“页面之间的通信”,而且说是有三种方法!这不,折腾了几天,算是小有成果,且把相关的东西从头到尾理一下,一起分享。

目录一.window对象的open方法1.window对象2.window对象的open方法(1)window.open(URL,name,features,replace)(2)用window.open方法实现页面通信3.window.showModalDialog(1)window.showModalDialog(2)window.showModelessDialog(3)兼容性4.window的height和width(1)原生js的window.innerWidth和window.outerWidth(2)jquery innerWidth,outerWidth,clientWidth(3)改变窗口的height和width二.利用iframe1.frame2.iframe3.利用iframe实现页面通信(1)父页面控制子页面(2)子页面操作父页面三.利用postMessage1.web Workers2.postMessage3.利用postMessage实现页面间通信(1)父窗口往子窗口传递信息(2)子窗口往父窗口传递信息四.小结1.window.open2.window.showModalDialog3.iframe4.open with postMessage五.附录1.IE下本地测试脚本会出现启用ActiveX提示2.弹窗被浏览器拦截

由于我是带着复习的目的边学边写的,而且有些相关性不太大的图占位实在太大。。。上面目录中把最重要的核心部分标出来了,如果大家有什么建议或意见,欢迎留言~(我估摸着以后对js页面间的通信了解深入了,这篇也要重写0.0...)

一.window对象的open方法1.window对象Window对象:在浏览器BOM中相当于ECMA中的global全局变量。但是在以下方面有所不同:

A.全局变量不能通过delete操作符删除,但是直接在window对象上定义的属性可以

B.尝试访问未声明的变量会抛出错误,但是通过查询window对象,可以知道某个可能未声明的变量是否存在。

//这种没有写文件属性的代码直接在控制台输入就行,下同var a=window.xxx; //xxx不存在则a为undifined

w3cSchool对window对象的属性和方法总结

2.window对象的open方法(1)window.open(URL,name,features,replace) URL:(可选)为空则打开空白新窗口。

Name:(可选)子窗口的句柄,声明新窗口的名称。

Features (可选) 声明新窗口要显示的标准浏览器的特征(必须是打开空白窗口)。

Replace(可选) 为true的话则替换浏览历史中的当前条目(返回回不去),默认为false,创建新条目。

参数的详细介绍:

Name:值为用户按照标识符定义规则定义的字符串。除非最高层窗口(Top)是通过window.open()打开的,否则其window对象的name属性不会包含任何值(空字符串)。(可以为_self、_parent、_top、_blank)

如现在同一文件夹路径下有test.html,parent.html,和child.html三个文件,浏览器打开test.html,在控制台输入

window.open('parent.html','parent');window.name

此时会弹出parent.html窗口,并且在test.html控制台中显示"",即test.html(Top)的window.name属性value为空。然后在parent.html窗口的控制台中输入

window.name

可以看到"parent"字符串,也就是说parent.html的window对象name属性value为"parent"。现在回到test.html,控制台输入

//等同于<a href='child.html' target='parent'></a>window.open('child.html','parent');

运行之后可以发现test.html没动静,但是parent.html以_self的形式自动跳转到了child.html。(这里在一个窗口控制了另一个窗口的跳转,也算页面通信的一种吧)

小结一下:运行window.open('URL','Name');时,如果有名为Name的窗口或框架,则在该窗口或框架加载URL;否则,创建一个新窗口打开URL并命名其为Name。

Features:如果第二个参数Name并不是一个已经存在的窗口或框架,那么open方法会根据第三个参数设定的字符串创建一个新窗口或新标签页。不打开新窗口时,会忽略第三个参数。也就是说这个参数是用来设置新打开窗口的属性的。具体的属性见w3cschool上截图如下

示例:

window.open('parent.html','parent','width=300,height=300,toolbar=no');

(2)用window.open方法实现页面通信window.open方法返回打开URL对应窗口的Window对象的引用,当URL为空或不存在的时候返回Window about blank(FF中测试), 当被拦截的时候返回undefined(Opera中测试)。借这个返回值来实现页面间的通信。

注意顺序 test.html -> parent.html -> child.html

在test.html中用newWindow取得parent.html中Window的引用

var newWindow = window.open('parent.html', 'parent');

通过newWindow在test.html中操作parent.html。(前提是parent.html是由test.html打开的)

A.关闭parent.html

newWindow.close();

B.操作parent.html中的DOM

newWindow.document.body.innerHTML = 'your code here';

C.控制parent.html跳转(和上面的效果差不多)

newWindow.location.href='child.html'; //绝对URL也行 newWindow.location.href = 'http://www.baidu.com';

D.parent.html通过window.opener反向操作test.html (在parent.html中)

window.opener.document.body.innerHTML = '哈哈,我也能操作你!';

由于parent.html由test.html打开,因此parent.html的window.opener指向test.html的Window对象。为了维护这种联系,并不能用window.opener.close()来关闭test.html,并且当test.html被手动关闭的时候,parent.html的window.opener变成了null。值得注意的是parent.html依旧可以控制test.html的跳转,并且始终指向test.html的标签页(只要没关)。

有些浏览器(如IE8和Chrome)会在独立的进程中运行每一个标签页。当一个标签页打开另一个标签页时,如果两个Window对象之间需要彼此通信,那么新标签页就不能运行在独立的进程中。在Chrome中,将新创建标签页的opener设置为null(解除引用关系),即表示在单独的进程中运行新标签页。

3.window.showModalDialogwindow.showModalDialog称为模态对话框,window.showModelessDialog称为非模态对话框。好吧,不得不承认,之前没见过它们,out了~

(1)window.showModalDialogvar returnV = window.showModelDialog(URL, args, features);

参数:

URL :文档路径args : 用于向对话框传递参数, 类型不限features: 可选参数, 用于描述对话框

返回值:

新打开窗口的window对象

使用showModelDialog实现页面通信

父页面向子页面

//in test.htmlvar str = 'what?';window.showModalDialog('parent.html', str, 'dialogWidth=200px;dialogHeight=200px');

//in parent.htmlvar arr = window.dialogArguments; console.log(arr);

子页面向父页面

//in test.htmlvar str = window.showModalDialog('parent.html', '', 'dialogWidth=200px;dialogHeight=200px');alert(str);

//in parent.htmlwindow.returnValue="test!";

(2)window.showModelessDialog非模态对话框,打开时与模态对话框总是置顶不一样,非模态对话框可以进行其它操作。

// in test.htmlvar str = window.showModelessDialog('parent.html', '', 'dialogWidth=200px;dialogHeight=200px');alert(str.returnValue);

//in parent.htmlwindow.returnValue="test!";

(3)兼容性虽然我貌似把老古董翻出来了,但是测试模态对话框的兼容性不咋地啊。。。

window.showModalDialog兼容性

opera 28.0.1750.51 不兼容

chrome 43.0.2357.65 不兼容

IE,Firefox,360安全,360急速 支持

window.showModelessDialog兼容性

IE支持,但是上例返回object Window

opera,chrome,firefox,360系列均不支持

过了这么多年,模态对话框的支持依旧这么差,而且和alert()一样强制置顶,用户体验也不好,没能进入w3c的标准(上面图里面明显也没有)。故而这里就不细细讨论了,不建议使用,除非自己写个兼容性良好的插件,把它封装进去。如果有兴趣,建议参考http://www.cnblogs.com/jhxk/articles/1761347.html 。

4.window的height和width这一个应该大家都见过,这里只是参考高级程序设计第三版小结一下。

(1)原生js的window.innerWidth和window.outerWidth由于height和width实现其实是一样的,只是方向不一样罢了,这里就以width作为代表。

高级程序设计第三版上写着:

FF, IE, oPRea, safari中: innerWidth 返回页面视图区大小(减去边框),outerWidth 返回浏览器窗口本身的尺寸。

Chrome中:innerWidth = outerWidth 为视口(viewport) 尺寸

我测试了一下我的chrome,结果和上面的不一样,不知道它说的是哪一个版本。我的测试版本 41.0.2272.76,结果是chrome的显示结果和其余四种并没有什么不同。

另外,高三中获取页面视口大小的兼容性代码

var pageWidth = window.innerWidth, pageHeight = window.innerHeight;if (typeof pageWidth != 'number') { if (document.compatMode == 'CSS1Compat') { //页面是否处于标准模式 pageWidth = document.documentElement.clientWidth; pageHeight = document.documentElement.clientHeight; } else { //IE6混杂模式,chrome混杂模式两个执行语句都可用 pageWidth = document.body.clientWidth; pageHeight = document.body.clientHeight; }}

经FF和Chrome测试,在<!DOCTYPE html>的标准下,document.body.clientWidth返回body元素占位的宽度。没有<!DOCTYPE html>,则document.body.clientWidth表示视口宽度。而document.documentElement.clientWidth一直返回视口宽度。

(2)jquery innerWidth,outerWidth,clientWidth由于我用jquery用得比较多,当然也要测试一下咯。然而不管怎么测试,$(window).innerWidth == $(window).outerWidth。于是看一下源码

//jqery1.11.0// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methodsjQuery.each({ Height: "height", Width: "width"}, function(name, type) { jQuery.each({ padding: "inner" + name, content: type, "": "outer" + name }, function(defaultExtra, funcName) { // margin is only for outerHeight, outerWidth jQuery.fn[funcName] = function(margin, value) { var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航