I have a link in page_a.php
which opens in new tab using target="_blank"
.
<a href="page_b.php" target="_blank">Open Page B</a>
In the page B I have a script that will automatically close the tab/window once the user is no longer viewing it. My script looks like this:
<script type="text/javascript">
function handleVisibilityChange() {
if (document.visibilityState == "hidden") {
window.close();
console.log("hidden");
} else {
console.log("shown");
}
}
document.addEventListener('visibilitychange', handleVisibilityChange, false);
</script>
So I have:
localhost/test/page_a.php //loads jQuery
localhost/test/page_b.php //doesn't load jQuery
On page_b.php
I get the warning:
Scripts may close only the windows that were opened by it.
Since I am in-fact the one opening the window, is there a way to make this work?
The window must have been opened with JavaScript's window.open()
, not with a <a href="..." target="...">
link. See window.close()
documentation for more details.
One way to do this, for instance, is by listening for the click
event on the link, prevent the default action and then explicitly open the window with JavaScript:
<script type="text/javascript">
// wait for the DOM to have loaded
document.addEventListener( 'DOMContentLoaded', function( e ) {
let link = document.querySelector( 'some selector to get the proper link element' );
link.addEventListener( 'click', function( e ) {
// prevent window opening regularly
e.preventDefault();
// explicitly open with JavaScript
window.open( this.href, 'MyNewWindow' );
} );
} );
</script>
There are possible issues with this, though:
If a user accesses page_b.php
by some other means than through clicking your link, closing the window will not work either. You have to explicitly test whether the window was opened by your other window with window.opener
:
<script type="text/javascript">
/*
...
*/
// if this window has a reference to the window that opened this window
if( window.opener ) {
document.addEventListener('visibilitychange', handleVisibilityChange, false);
}
</script>
But as you can see in the documentation, window.opener
has its own issues as well.