在没有窗口参考的标签之间进行通信

时间:2016-10-18 20:12:35

标签: javascript html google-chrome service-worker

我使用以下内容打开包含一些页面内容的新标签(在新过程中)

var p = document.getElementById("myElement"); 
var a = document.createElement('a');
a.setAttribute('href',".../mypage.html");
a.setAttribute('rel',"noreferrer");
a.setAttribute('target',"_blank");
p.appendChild(a);
a.click();

http://news.softpedia.com/news/Force-Google-Chrome-to-Open-Links-in-New-Processes-128962.shtml

此功能正常,新标签已打开,其中包含myPage.html内容。

假设这是myPage(仅用于示例...)我该如何访问它?

<!DOCTYPE html>
<html>
<body>

<h1> Heading</h1>
<p> paragraph.</p>
 <button type="button">Click Me!</button>

</body>
</html>
  

现在让我们转到棘手/高级:)部分......

当您使用window.open我无法使用)时,这很简单,因为您可以使用各种技术。

 1. using window object
 2. post message
 https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
 3. cookies 
 4. localStorage

但是在这里我打开这个新页面时没有使用window.open

获得的引用

我的问题是:

  

如果我想更改某些内容,如何访问此新标签?

4 个答案:

答案 0 :(得分:4)

父页面JavaScript:

var lastMessage;
setInterval(function() {
  var message = localStorage.getItem('message-to-parent');
  if (message && message !== lastMessage) {
    lastMessage = message;
    // your code here
    alert('There is a new message for you: ' + message);
  }
}, 100);

子页面JavaScript:

localStorage.setItem('message-to-parent', 'hello, my parent!');

如果你有很多动画和其他巨大的JS代码,我建议增加定时器间隔,或者更好地解决window的问题。

答案 1 :(得分:3)

我遇到了类似的问题并构建了一个小型的lib来通过localStorage进行函数调用,并且可以使用paramter。你可以找到它here。 所有browsers目前都不支持服务工作者。

以下是如何使用它的示例:

//Register a function: 
RegisterLocalStorageFunction("test", function(param){ 
    return param+param; 
});

//Call a function: 
let str = "testing"; 
CallLocalStorageFunction("test",str,function(para){ 
    console.log(para); 
});

在您的背景下:

RegisterLocalStorageFunction("CallAlert", function(param){ 
    alert(param);
    return "Success"; 
});
var p = document.getElementById("myElement");
var a = document.createElement('a');
a.setAttribute('href',".../mypage.html");
a.setAttribute('rel',"noreferrer");
a.setAttribute('target',"_blank");
p.appendChild(a);
a.click();

在你的另一个窗口:

<!DOCTYPE html>
<html>
<body>
<h1> Heading</h1>
<p> paragraph.</p>
<button type="button" onclick="btnClick()">Click Me!</button>
<script>
    function btnclick(){
        CallLocalStorageFunction("CallAlert","Hello from the other tab",function(para){ 
            console.log("para"); 
        });
}
</script>
</body>
</html>

双方必须在同一个域上,否则他们无法访问相同的localStorage。 使用我在github上的currrent代码,我使用setInterval来循环存储。有一个storage event,它被激发到所有其他选项卡和窗口,但不是同一个选项卡。 我将重写lib以使用更清晰的方法来处理事件,但是现在这应该可以解决问题。

<强>更新

在存储库中,您可以找到基于&#39;存储&#39;存储的通信器2。事件

<强>更新

Here是一个托管的工作示例。请记住允许弹出窗口。

答案 2 :(得分:1)

您必须在触发click事件之前附加DOMNodeInserted-listener,然后才能访问此window-object。

// assuming that all inserted alements are links or a-tags
// this code must run before the code that adds the a-element
document.addEventListener("DOMNodeInserted", function (ev) {
      var link = ev.target;
      var oldRef = link.href;
      link.onclick = function(event){
        event.preventDefault();
        var childWindow = window.open(oldRef);
        childWindow.onload = function(){
          console.log('at this point you can interact with this newly opened window-object: ',childWindow);
        };
      };
});

//...
// some other code
//...

var p = document.getElementById("myElement"); 
var a = document.createElement('a');
a.setAttribute('href',".../mypage.html");
a.setAttribute('rel',"noreferrer");
a.setAttribute('target',"_blank");
p.appendChild(a);
a.click();

希望这有帮助。

答案 3 :(得分:1)

您可以使用SharedWorker在不同的浏览上下文之间进行通信。

请参阅Can we refer to javascript variables across webpages in a browser session?

您也可以使用storage事件Can the mechanism that loads the worker in Shared Web Workers be modified?