在没有窗口参考的选项卡dom之间进行通信[重复]
Posted
技术标签:
【中文标题】在没有窗口参考的选项卡dom之间进行通信[重复]【英文标题】:Communicate between tabs dom without window ref [duplicate] 【发布时间】:2017-02-28 06:14:14 【问题描述】:我使用以下内容打开包含一些页面内容的新选项卡(在新进程中),
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 获得的参考
我的问题是:
如果我想更改某些内容,如何访问这个新的标签 dom
【问题讨论】:
嗨,我在发帖前给你 +1 搜索 @MarnyA.López - 谢谢 :) 我希望您对同源策略没有任何问题。 1)任何页面都可以是“父”吗? 2)您需要双向发送消息吗? (父母 -> 孩子或孩子 -> 父母) @fremail - 目前我没有域问题...我需要从“子选项卡”向“父选项卡”发送消息,如果您有想法请提供一些示例,谢谢! 你说你不能使用window.open API然后说你根本不能使用window?怎么会?要求避免 XY... 【参考方案1】:父页面 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
。
【讨论】:
谢谢,这个解决方案将如何在浏览器中执行,我的意思是从性能或负载... @JohnJerrby 计时器将添加一个作业(回调函数)来检查消息,延迟为 100 毫秒,但问题是该作业可能会晚于 100 毫秒运行。在此处阅读更多关于 JS 计时器的信息ejohn.org/blog/how-javascript-timers-work 如果您使用 100 毫秒或更长的延迟并且间隔的回调函数很简单(如我的代码),您可能对性能保持冷静。 谢谢! ,我不确定我是否可以使用此解决方案,因为它不可靠...(正如您发布的链接所说...),您认为我可以使用其他解决方案吗? @JohnJerrby 您是否尝试使用此解决方案? ***.com/a/28230846/3816979 我读了这篇文章(我在我的问题上放了一个链接)但是有一个窗口 $(window).on('storage', message_receive); , 有一种方法可以将它绑定到其他东西上吗?如果这样可以很好,我可以使用它...【参考方案2】:我遇到了类似的问题,并构建了一个小型库,以通过 localStorage 进行函数调用,并可以使用参数。你可以找到它here。 目前并非所有 browsers 都支持 Service Worker。
这是一个如何使用它的示例:
//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 上的当前代码,我使用 setInterval 在存储中循环。 有一个storage event,它会被触发到所有其他选项卡和窗口,但不会触发到同一个选项卡。 我将重写库以对事件使用更简洁的方法,但现在这应该可以解决问题。
更新
在存储库中,您可以找到基于 'storage' 事件的 communicator2。
更新
Here 是托管的工作示例。请记住允许弹出窗口。
【讨论】:
谢谢,如果您能在我的上下文中举例说明,如果您需要其他信息...谢谢! 谢谢 :),我现在试试,让你知道... 没问题,我推荐版本 2。如果您有任何问题,请告诉我。 谢谢,但我不能使用版本 2,因为你使用那里的窗口,我没有窗口对象,因为我使用 a.setAttribute('href',".../mypage.html"); a.setAttribute('rel',"noreferrer"); a.setAttribute('target',"_blank");但也许我想念一些…… 是的,但是由于我们在使用本地存储时遇到了一些安全问题,我正在尝试检查是否可以使用从安全方面更好的 sessionStorage,如果您知道如何使其与会话一起使用存储请告诉我。非常感谢!【参考方案3】:您必须在触发 click 事件之前附加一个 DOMNodeInserted-listener,然后您才能访问此窗口对象。
// 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();
希望这会有所帮助。
【讨论】:
谢谢,但我不能使用打开窗口...:(我只能使用 a.tag... 请试一试:)【参考方案4】:您可以使用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?
【讨论】:
以上是关于在没有窗口参考的选项卡dom之间进行通信[重复]的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript;具有相同来源的选项卡/窗口之间的通信[重复]