我可以将JavaScript变量传递给另一个浏览器窗口吗?


72

我有一个页面,其中会产生一个弹出浏览器窗口。我在父浏览器窗口中有一个JavaScript变量,我想将其传递给弹出的浏览器窗口。

有没有办法做到这一点?我知道可以在同一浏览器窗口中跨框架完成此操作,但是我不确定是否可以在浏览器窗口中跨框架完成操作。

Answers:


43

如果这些窗口来自同一安全域,并且您对另一个窗口有引用,可以。

Javascript的open()方法返回对创建的窗口的引用(如果重用现有窗口,则返回现有窗口)。以这种方式创建的每个窗口都将一个属性应用到它,该属性指向创建它的窗口“ window.opener”。

然后,可以使用DOM(取决于安全性)来访问另一个对象或其文档,框架等的属性。


17
自问这个问题以来,情况已经改变。现在,在较新的浏览器上,也可以通过调用来在不同安全域的Windows之间传递消息window.postMessage
2013年

105

将代码放入问题中,您可以在父窗口中执行以下操作:

var thisIsAnObject = {foo:'bar'};
var w = window.open("http://example.com");
w.myVariable = thisIsAnObject;

或在新窗口中显示以下内容:

var myVariable = window.opener.thisIsAnObject;

我更喜欢后者,因为无论如何您可能都需要等待新页面加载,以便您可以访问其元素或任何您想要的东西。


我不了解{foo:'bar'}。你能帮我这个忙吗?
Masoud Sahabi

1
@MasoudSahabivar x = {foo: 'bar'}只是用于创建对象的紧凑字面量语法。与var x = new Object(); x.foo = 'bar';
sergiopereira

我正在使用第一个,它在Chrome中工作正常,但IE似乎抱怨。而且很难达到断点。
styfle

1
这将是很棒的,但是现在IE10抱怨它,这目前不是跨浏览器兼容性的最佳方法。
7dr3am7

1
@ 7dr3am7,我明白了,我得到“权限被拒绝”。但是,如果我在第二个窗口中使用第二种方法,则可以正常工作。
维克多

8

是的,脚本可以访问其具有相同句柄的域中的其他窗口的属性(通常通过window.open/opener和window.frames / parent获得)。通常,调用另一个窗口上定义的函数比直接使用变量来管理更容易管理。

但是,窗口可能会死掉或继续移动,浏览器在处理窗口时会有所不同。在尝试调用窗口之前,请检查窗口(a)仍处于打开状态(!window.closed)和(b)具有您期望的功能。

像字符串之类的简单值很好,但是通常不要在窗口之间传递诸如函数,DOM元素和闭包之类的复杂对象。如果子窗口从其打开器中存储对象,则打开器将关闭,该对象可能会“死”(在某些浏览器中,例如IE),或导致内存泄漏。可能会发生奇怪的错误。


5

在窗口之间传递变量(如果您的窗口在同一域中)可以通过以下方法轻松完成:

  1. 饼干
  2. localStorage。只要确保您的浏览器支持localStorage,然后执行变量维护权限(添加/删除/删除)即可保持localStorage干净。

3

在您的父窗口中:

var yourValue = 'something';
window.open('/childwindow.html?yourKey=' + yourValue);

然后在childwindow.html中:

var query = location.search.substring(1);
var parameters = {};
var keyValues = query.split(/&/);
for (var keyValue in keyValues) {
    var keyValuePairs = keyValue.split(/=/);
    var key = keyValuePairs[0];
    var value = keyValuePairs[1];
    parameters[key] = value;
}

alert(parameters['yourKey']);

在解析键/值对时,可能应该进行很多错误检查,但此处未包括在内。也许有人可以在以后的答案中提供更具包容性的Javascript查询字符串解析例程。


3

可以将消息从“父”窗口传递到“子”窗口:

在“父窗口”中打开孩子

    var win = window.open(<window.location.href>, '_blank');    
       setTimeout(function(){
                    win.postMessage(SRFBfromEBNF,"*")
                  },1000);
    win.focus();

根据上下文替换

在“孩子”里

    window.addEventListener('message', function(event) {
        if(event.srcElement.location.href==window.location.href){
        /* do what you want with event.data */
        }
    }); 

if测试必须根据上下文进行更改


2

您可以轻松地传递变量,并在父窗口中引用事物:

// open an empty sample window:
var win = open("");
win.document.write("<html><body><head></head><input value='Trigger handler in other window!' type='button' id='button'></input></body></html>");

// attach to button in target window, and use a handler in this one:
var button = win.document.getElementById('button');

button.onclick = function() {
     alert("I'm in the first frame!");   
}

如所写,这在人们正在运行adblock等的现实世界中是行不通的。通过向open添加参数以使其在单独的窗口中打开(而不是tab,因为我已配置FF),我能够让这个工作在Firefox中。但是弹出窗口在Chrome中被阻止。因此,它很简单而且很有效,但是离可行的解决方案还有点距离。
尼克·赖斯

1

是的,只要两个窗口都在同一域中就可以完成。window.open()函数将返回新窗口的句柄。子窗口可以使用DOM元素“ opener”访问父窗口。


1

对我来说,以下行不通

var A = {foo:'bar'};
var w = window.open("http://example.com");
w.B = A;

// in new window
var B = window.opener.B;

但这有效(注意变量名)

var B = {foo:'bar'};
var w = window.open("http://example.com");
w.B = B;

// in new window
var B = window.opener.B;

另外,var B应该是全局的。


0

另外,您也可以将其添加到URL中,然后让脚本语言(PHP,Perl,ASP,Python,Ruby等)来处理它。就像是:

var x = 10;
window.open('mypage.php?x='+x);

0

我一直在努力将参数成功传递给新打开的窗口。
这是我想出的:

function openWindow(path, callback /* , arg1 , arg2, ... */){
    var args = Array.prototype.slice.call(arguments, 2); // retrieve the arguments
    var w = window.open(path); // open the new window
    w.addEventListener('load', afterLoadWindow.bind(w, args), false); // listen to the new window's load event
    function afterLoadWindow(/* [arg1,arg2,...], loadEvent */){
        callback.apply(this, arguments[0]); // execute the callbacks, passing the initial arguments (arguments[1] contains the load event)
    }
}

示例调用:

openWindow("/contact",function(firstname, lastname){
    this.alert("Hello "+firstname+" "+lastname);
}, "John", "Doe");

现场例子

http://jsfiddle.net/rj6o0jzw/1/



-1

是的,浏览器清除所有参考。一个窗户。因此,您必须在主窗口中搜索某类的ClassName或将cookie用作Javascript自制引用。

我的项目页面上有一个收音机。然后打开收音机,它在一个弹出窗口中启动,我控制主页上的主窗口链接并显示播放状态,在FF中这很容易,但是在MSIE中则不那么容易。但这是可以完成的。


-2

如果您对创建的窗口有引用,并且在同一个域中,则window.open()函数也将允许此操作。如果在服务器端使用了该变量,则应该使用$ _SESSION变量(假设您正在使用PHP)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.