Accessing the Content of Other Tabs in a Browser

Accessing the content of other tabs in a browser

You could use HTML5 cross-window messaging (archive.org link...but that's kind of cutting edge.

Even in that case, you'd probably need to hijack the <a> tag 'click' event with JavaScript and open the window yourself so that you'd have access to the new window object for posting messages.

Accessing other tabs/windows in a browser via JavaScript

As far as I understand, you cannot access the browser's tab array (certainly not through JavaScript). This would be a security breach on the client side. You should think of each browser tab as a browser instance of it's own - unaware of any other tab.

Using javascript to detect the domains of other tabs?

For privacy reasons, you could only do that in a browser extension, and only if the extension has been given the tabs permission.

See here for more information about the chrome.tabs API.

async function getInactiveTabs() {
return await chrome.tabs.query({ active: false, currentWindow: true });
}

accessing other tab from one window

As far as I know, this isn't possible. The browser wouldn't allow you to manipulate the browser's lower functions in a regular environment. It would ignore it or show a security error come up.

Communication between tabs or windows

You may better use BroadcastChannel for this purpose. See other answers below. Yet if you still prefer to use localstorage for communication between tabs, do it this way:

In order to get notified when a tab sends a message to other tabs, you simply need to bind on 'storage' event. In all tabs, do this:

$(window).on('storage', message_receive);

The function message_receive will be called every time you set any value of localStorage in any other tab. The event listener contains also the data newly set to localStorage, so you don't even need to parse localStorage object itself. This is very handy because you can reset the value just right after it was set, to effectively clean up any traces. Here are functions for messaging:

// use local storage for messaging. Set message in local storage and clear it right away
// This is a safe way how to communicate with other tabs while not leaving any traces
//
function message_broadcast(message)
{
localStorage.setItem('message',JSON.stringify(message));
localStorage.removeItem('message');
}

// receive message
//
function message_receive(ev)
{
if (ev.originalEvent.key!='message') return; // ignore other keys
var message=JSON.parse(ev.originalEvent.newValue);
if (!message) return; // ignore empty msg or msg reset

// here you act on messages.
// you can send objects like { 'command': 'doit', 'data': 'abcd' }
if (message.command == 'doit') alert(message.data);

// etc.
}

So now once your tabs bind on the onstorage event, and you have these two functions implemented, you can simply broadcast a message to other tabs calling, for example:

message_broadcast({'command':'reset'})

Remember that sending the exact same message twice will be propagated only once, so if you need to repeat messages, add some unique identifier to them, like

message_broadcast({'command':'reset', 'uid': (new Date).getTime()+Math.random()})

Also remember that the current tab which broadcasts the message doesn't actually receive it, only other tabs or windows on the same domain.

You may ask what happens if the user loads a different webpage or closes his tab just after the setItem() call before the removeItem(). Well, from my own testing the browser puts unloading on hold until the entire function message_broadcast() is finished. I tested to put some very long for() cycle in there and it still waited for the cycle to finish before closing. If the user kills the tab just in-between, then the browser won't have enough time to save the message to disk, thus this approach seems to me like safe way how to send messages without any traces.

Display data on different browser tabs

Yes, if either:

  1. Your code opened the other tab (via window.open), or

  2. The window has a name (such as one assigned via the target attribute on a link, e.g. target="otherwindow")

Additionally, the window's content must be on the same origin as the document you're interacting with it from, or you'll be blocked by the Same Origin Policy.

1. If you're opening it via window.open

window.open returns a reference to the window object for the window that was opened, which (assuming it's on the same origin) you can do things with. E.g.:

var wnd = window.open("/some/url");

// ...later, when it's loaded...

var div = wnd.document.createElement('div');
div.innerHTML = "content";
wnd.document.appendChild(div);

You can use all of the usual DOM methods. If you load a library in the other window, you can use that as well. (It's important to understand that the two windows have two different global namespaces, they're not shared.)

Here's a full example. I used jQuery in the below just for convenience, but jQuery is not required for this. As I said above, you can use the DOM directly (or another library if you like):

Live Copy | Live Source

HTML:

<button id="btnOpen">Open Window</button>
<button id="btnAdd">Add Content</button>
<button id="btnRemove">Remove Content</button>

JavaScript:

(function($) {
var btnOpen,
btnAdd,
btnRemove,
wnd,
wndTimeout,
wnd$,
newContentId = 0;

btnOpen = $("#btnOpen");
btnAdd = $("#btnAdd");
btnRemove = $("#btnRemove");
updateButtons();

btnOpen.click(openWindow);
btnAdd.click(addContent);
btnRemove.click(removeContent);

function updateButtons() {
btnOpen[0].disabled = !!wnd;
btnAdd[0].disabled = !wnd$;
btnRemove[0].disabled = !wnd$;
}

function openWindow() {
if (!wnd) {
display("Opening window");
wnd$ = undefined;
wndTimeout = new Date().getTime() + 10000;
wnd = window.open("/etogel/1");
updateButtons();
checkReady();
}
}

function windowClosed() {
display("Other window was closed");
wnd = undefined;
wnd$ = undefined;
updateButtons();
}

function checkReady() {
if (wnd && wnd.jQuery) {
wnd$ = wnd.jQuery;
wnd$(wnd).on("unload", windowClosed);
updateButtons();
}
else {
if (new Date().getTime() > wndTimeout) {
display("Timed out waiting for other window to be ready");
wnd = undefined;
}
else {
setTimeout(checkReady, 10);
}
}
}

function addContent() {
var div;

if (wnd$) {
++newContentId;
display("Adding content '" + newContentId + "'");
wnd$("<div>").addClass("ourcontent").html("Added content block #" + newContentId).appendTo(wnd.document.body);
}
}

function removeContent() {
var div;

if (wnd$) {
div = wnd$("div.ourcontent").first();
if (div[0]) {
display("Removing div '" + div.html() + "' from other window");
div.remove();
}
else {
display("None of our content divs found in other window, not removing anything");
}
}
}

function display(msg) {
$("<p>").html(String(msg)).appendTo(document.body);
}

})(jQuery);

2. If you're opening it via a link with target

window.open can find and return a reference to that window:

var wnd = window.open("", "otherwindow");

Note that the URL argument is empty, but we pass it the name from the target attribute. The window must already be open for this to work (otherwise it will open a completely blank window).

Here's the above example, modified to assume you've opened the window via <a href="..." target="otherwindow">...</a>:

Live Copy | Live Source

HTML:

<a href="/etogel/1" target="otherwindow">Click to open the other window</a>
<br><button id="btnGet">Get Window</button>
<button id="btnAdd">Add Content</button>
<button id="btnRemove">Remove Content</button>

JavaScript:

(function($) {
var btnGet,
btnAdd,
btnRemove,
wnd,
wndTimeout,
wnd$,
newContentId = 0;

btnGet = $("#btnGet");
btnAdd = $("#btnAdd");
btnRemove = $("#btnRemove");
updateButtons();

btnGet.click(getWindow);
btnAdd.click(addContent);
btnRemove.click(removeContent);

function updateButtons() {
btnGet[0].disabled = !!wnd;
btnAdd[0].disabled = !wnd$;
btnRemove[0].disabled = !wnd$;
}

function getWindow() {
if (!wnd) {
display("Getting 'otherwindow' window");
wnd$ = undefined;
wndTimeout = new Date().getTime() + 10000;
wnd = window.open("", "otherwindow");
updateButtons();
checkReady();
}
}

function windowClosed() {
display("Other window was closed");
wnd = undefined;
wnd$ = undefined;
updateButtons();
}

function checkReady() {
if (wnd && wnd.jQuery) {
wnd$ = wnd.jQuery;
wnd$(wnd).on("unload", windowClosed);
updateButtons();
}
else {
if (new Date().getTime() > wndTimeout) {
display("Timed out looking for other window");
wnd = undefined;
updateButtons();
}
else {
setTimeout(checkReady, 10);
}
}
}

function addContent() {
var div;

if (wnd$) {
++newContentId;
display("Adding content '" + newContentId + "'");
wnd$("<div>").addClass("ourcontent").html("Added content block #" + newContentId).appendTo(wnd.document.body);
}
}

function removeContent() {
var div;

if (wnd$) {
div = wnd$("div.ourcontent").first();
if (div[0]) {
display("Removing div '" + div.html() + "' from other window");
div.remove();
}
else {
display("None of our content divs found in other window, not removing anything");
}
}
}

function display(msg) {
$("<p>").html(String(msg)).appendTo(document.body);
}

})(jQuery);


Related Topics



Leave a reply



Submit