首页 > 网站 > WEB开发 > 正文

js 页面间的通信

2024-04-27 14:06:19
字体:
来源:转载
供稿:网友

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  二.利用iframe    1.frame    2.iframe    3.利用iframe实现页面通信      (1)父页面控制子页面      (2)子页面操作父页面  三.利用postMessage    1.web Workers    2.postMessage    3.利用postMessage实现页面间通信      (1)父窗口往子窗口传递信息      (2)子窗口往父窗口传递信息  四.小结    1.window.open    2.window.showModalDialog    3.iframe    4.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.showModalDialog

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

  (1)window.showModalDialog

var 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"),
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表