Difference between document.hidden vs document.hasFocus() - javascript

Please explain the difference between document.hidden , the HTML5 Page Visibility API and document.hasFocus(). I am doing a project which pops HTML5 Desktop Notification when the tab is not focused. I am kind of confused which one to use.

The hidden attribute is defined like this:
On getting, the hidden attribute MUST return true if the
Document contained by the top level browsing context (root
window in the browser's viewport) is not visible at all. The attribute
MUST return false if the Document contained by the top level
browsing context is at least partially visible on at least one
screen.
If the defaultView of the Document is null, on getting, the
hidden attribute MUST return true.
The hasFocus method is defined like this
The hasFocus() method on Document objects must return true if
the Document's browsing context is focused, and all its
ancestor browsing contexts are also focused, and the top-level
browsing context has the system focus. If the Document
has no browsing context or if its browsing context has no
top-level browsing context, then the method will always return
false.
For example, if you open a page in a foreground tab, and then open another window, the tab will (or may) still be partially visible, so hidden returns false. However, the new window has focus, so hasFocus() returns false for the tab.
If you run the following snippet, the document inside the iframe will be visible but won't have focus (this stackoverflow page is focused instead):
document.body.innerHTML =
'<p>hidden: ' + document.hidden + '</p>' +
'<p>hasFocus: ' + document.hasFocus() + '</p>';
But in this other one, since you click the button inside the iframe, it is both visible and focused:
document.getElementsByTagName('input')[0].onclick = function() {
document.body.innerHTML =
'<p>hidden: ' + document.hidden + '</p>' +
'<p>hasFocus: ' + document.hasFocus() + '</p>';
};
<input type="button" value="Click me!" />

TLDR:
document.hidden: returns true if tab is open and is not at all visible. Opening another chrome window and covering the open tab would make it return true
document.hasFocus(): returns true if the tab is the open tab and no other window has focus. Opening a chrome window would make that window have focus, so the open tab in the background, although visible, would return false

Related

Reference to parent window after allow popup window once

So I'm trying to test whenever popup windows are enabled for my site. My window should be blocked by browser's popup blocker, unless they are already allowed. If popup windows are allowed everything works fine, since I can test whenever the window was opened directly in my parent page.
Problem is that I still want to mark the test as sucessfull if the user allows to open popup window later by allowing the popup window to open. Only way for me to do that is by calling some function on my parent page, but window opened this way has null window.opener and I can't set the object on child window directly from my parent window since I don't know when will it open.
Is there any way to get reference to my parent window from child window when it's opened this way?
Or any other workaround that could call function on my parent window whenever the child window is sucessfully opened?
Maybe event event that I could hook up to whenever such window is opened, but I couldn't find any such event.
Sample code:
function () {
var myWin = window.open('popupWin.html', '_blank', 'resizable=no,scrollbars=no,height=1,width=1', true);
if (!myWin || myWin == null || typeof (myWin) == 'undefined')
SetPopupResult(false);
else {
SetPopupResult(true);
myWin.close();
}
}
popupWin.html is empty page with following script:
<script>
window.opener.SetPopupResult(true); //throws Cannot read property 'SetPopupResult' of null
setTimeout(function () {
window.close();
}, 1000);
</script>
Edit: Forgot to mention this is issue in Google-Chrome so far, firefox doesn't seem to have this problem and window.opener is correct, IE's behaivor is different as it refreshes the page and openes the popup window like they were enabled.

Get hosting XULDocument for a ContentWindow or HTMLDocument in Firefox extension?

I have an Firefox Extension with a XUL overlay containing some Javascript with some event handlers. Among those is an EventListener for DOMContentLoaded. I have a second overlay I only want to load when visiting a certain website.
Here's some of the code I have so far:
var appcontent = document.getElementById("appcontent"); // browser
if (appcontent) appcontent.addEventListener("DOMContentLoaded", onPageLoad, true);
function onPageLoad(event) {
var doc = iEvent.originalTarget; // doc is document that triggered "onload" event
var win = doc.defaultView;
if (doc.nodeName != 'document') return; // only documents
if (win != win.top) return; //only top window.
if (win.frameElement) return; // skip iframes/frames
if(doc.location.href.search('http://somewebsite.com/') > -1) {
//Find XULDocument somehow
//var xulDoc = ??????;
xulDoc.loadOverlay('chrome://myextension/content/secondoverlay.xul', null);
}
}
How can I retrieve the XULDocument hosting the DOM, given the DOMContentLoaded event data?
Well, the XUL window is just window, aka. the global scope.
So the following two lines should both work and should be the same:
window.document.loadOverlay(...);
document.loadOverlay(...);
However, this most is not really what you want, because the XUL window is still the main browser.xul which hosts all content windows. There is no dedicated XUL window per content window!
Loading the second overlay will overlay the whole browser window, not just the "tab" (or whatever) and will stay once you close the tab (content window) or navigate away.
Now, the question is: What do you really want to achieve?
Display some UI (toolbar button, menu, whatever) only for certain pages? Then usually you'd overlay all your stuff once (on the initial load, i.e. in the "first" overlay) and just hide/show your UI according to your rules. See Tabbed Browser for some code snippets when dealing with tab switching and/or page loads.
Or you really want to apply something to the content window itself. Then you'd usually just modify the DOM of the content window directly.

How do identify whether the window opened is a pop up or a tab?

I have been facing a problem.I am able to open a window using window.open method.If I specify the height and width of the window,it opens as a pop up window.If no parameters is given for height or width,then it opens in a new tab.
Is there any property through which I can determine window opened was a pop up or a new tab?
Thank you
Malcolm X
Edit: I have been looking into this a little further.
Seems like there is no different "type" on these windows, simply different options.
A way I found to check if it was a tab or window is to check window.menubar.visible.
For the tab, which is a full and normal window it is true, and for the pop-up the menu is hidden and therefore false. Same applies to window.toolbar.visible.
Works in FF and Chrome at least. Unfortunately not in IE. (Testing done in IE8, which is the version I have installed. For testing of course..)
Example:
if(window.menubar.visible) {
//Tab
} else {
//"Child" Window
}
Found this thread: Internet Explorer 8 JS Error: 'window.toolbar.visible' is null or not an object
If you specify width and height, it means that you also have to specify the name parameter. This can be used in the same way target in an a tag is used, and defaults to _blank.
If you do not specify width and height I assume you also don't specify name and therefore it is opened with name=_blank, which means a new Tab.
If you specify width and height, are you setting a custom name? Doing so results in a child window. If you specify a name, or empty string as name, I suggest you try name:_blank if you want it to be a new tab.
If the window was opened with a name, you can always the window.parent from the child window. If you open with _blank I am not sure if you can get the window.parent
w3schools Window Open
I'm not quite sure what you mean in your question but from what I understand, you might want to use the HTML target attribute:
_blank Opens the linked document in a new window or tab
_self Opens the linked document in the same frame as it was clicked (this is default)
_parent Opens the linked document in the parent frame
_top Opens the linked document in the full body of the window
framename Opens the linked document in a named frame
Source: http://www.w3schools.com/tags/att_a_target.asp
You can detect that using onblur, by checking whether the focus is missed or not
<html>
<head>
<script>
function newTab() {
document.getElementById("demo").innerHTML = "New tab opened!<br><br>refesh this page to recheck ";
}
window.onblur = newTab;
</script>
</head>
<body>
<div id="demo">
Open a new tab and then check this page
</div>
</body>
</html>

Find window previously opened by window.open

We've got the following situation, running from a single domain:
Page A uses window.open() to open a named window (a popup player). window.open() gives page A a reference to the window.
User now reloads page A. The reference to the named window is lost. Using window.open() to "find" the window has the unfortunate side effect of reloading it (undesirable). Is there any other way to get a reference to this window?
Try this:
var playerUrl = 'http://my.player...';
var popupPlayer= window.open('', 'popupPlayer', 'width=150,height=100') ;
if(popupPlayer.location.href == 'about:blank' ){
popupPlayer.location = playerUrl ;
}
popupPlayer.focus();
It will open a blank window with a unique name. Since the url is blank, the content of the window will not be reloaded.
AFAIK, no there isn't..
A kind-of-dirty-but-i-guess-it-will-work hack would be to periodically reset the reference on the parent window from within the popup using window.opener, with something like this code:
setInterval(function() {
if(window.opener) {
window.opener.document.myPopupWindow = window
}
}, 100)
In the parent window, you'll be able to access document.myPopupWindow, even after a reload (well, 100ms after the reload). This should work cross browser.
Actually what you did is destroy the parent (page A) of the created window (Popup), so it has no more reference to the original parent therefore you can't get a direct reference.
The only solution I can think of is using a browser that offers you added javascript capability to cycle through active windows (tabs) and find one that has a special property (ie: your reloaded page A) that gets recognized by the popup.
Unfortunately I guess only firefox has some added capability or extension that gives you this flexibility. (it is also a security risk though)
This should work. Add this code in the popup:
function updateOpener() {
if (window.opener)
window.opener.document.myPopupWindow = window;
else
setTimeout(updateOpener, 100);
}
updateOpener();
And this in onload of the parent window. To make sure myPopupWindow have been set wait 100 ms before accessing it.
setTimeout(function() {
if (document.myPopupWindow)
document.myPopupWindow.focus();
}, 100);
If all the windows share a common Url origin you can register a ServiceWorker and then access all windows from the ServiceWorker: https://developer.mozilla.org/en-US/docs/Web/API/Clients
AFAIK You won't be able to pass a reference to other windows from WorkerService to your window but you can establish communications with the ServiceWorker via
https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage
https://developer.mozilla.org/en-US/docs/Web/API/Client/postMessage
It Might help someone, If you opened an child tab and after refreshing the parent tab, you still want to focus on that child tab instead of opening new child tab: -
const chatPopup = window.open('', 'chatPopup');
if (chatPopup.location.href === 'about:blank' || !chatPopup.location.href.includes('/chat')) {
this.openNewWindow = window.open('/chat', 'chatPopup');}

I need to open a new window in the background with JavaScript, and make sure the original is still focused

I have a window I'm opening with a Javascript function:
function newwindow()
{
window.open('link.html','','width=,height=,resizable=no');
}
I need it that once the new window opens that the focus returns to the original window.
How can I do that?
And where do I put the code - in the new window, or the old one?
Thanks!
This is known as a 'pop-under' (and is generally frowned upon... but I digress).. It should give you plenty to google about
You probably want to do something like:
var popup = window.open(...);
popup.blur();
window.focus();
Which should set the focus back to the original window (untested - pinched from google). Some browsers might block this technique.
After calling window.open, you may try to use
window.resizeTo(0,0);
window.moveTo(0,window.screen.availHeight+10);
this way can not really open window in background, but works in similar way. Chrome works fine, did not try other browser.
If Albert's solution doesn't work for you and you actually want the window visible, but to be opened behind the current window, you can try opening a new tab in the opener window and closing it right away, this will bring the focus back to the opener window.
window.open('link.html','','width=,height=,resizable=no');
window.open().close();
However, I believe whether the second window opens in a tab or a new window depends on your browser settings.
Please don't use "pop-unders" for evil.
You can use either
"blur" or
"focus" to do that required action.
"blur"
function newwindow()
{
var myChild= window.open('link.html','','width=,height=,resizable=no');
myChild.blur();
}
"focus"
function newwindow()
{
window.open('link.html','','width=,height=,resizable=no');
window.focus();
}
Put the code in your parentWindow (i.e. the window in which you are now)
Both will work.
tl;dr - in 2022 - ctrl/cmd clicking on a button and window.open(url, "_blank") in a javascript button handler's for loop will open multiple tabs in the background in Chrome.
I'm looking for this as of 2022 and none of the answers here worked (here and everywhere else I looked). My use case is clicking a button in a (progressive) web app which opens deep links to items in a list in background tabs (i.e. not "for evil").
It never occurred to me that ctrl/cmd + clicking on the button would open tabs in the background, but it does just as if the user clicked on an anchor tag itself directly - but only in Chrome. Combined with Chrome's relatively recent tab grouping feature, this can be very useful inside PWAs.
const isMozilla =
window?.navigator?.userAgent?.toString().toLowerCase().includes('firefox') ?? false;
for (let index = 0; index < urls.length; index++) {
const url = isMozilla ? urls.reverse()[index] : urls[index];
window.open(url, "_blank");
}
Note: I reverse() the array on Mozilla to get the order of newly created tabs as the user would expect them.
You can just use '_self'. It will be stay to the same page an
window.open(url, '_self');

Categories