I am creating a game in which players have pop window. I am trying to call timer function from parent to player2 popup
I have googled and put this code in parent
var Popup = window.open("player2.php", "bpPopup",'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=420,height=300,left = 490,top = 262');
Popup.focus();
Popup.calltimer();
and in player2.php
function calltimer() {
alert('timer 2 called');
}
Attach a load event to the popup and then call the function though the popups window object.
<script>
var Popup = window.open("./player2.php", "bpPopup", 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=420,height=300,left = 490,top = 262');
Popup.focus();
Popup.addEventListener('load', function() {
Popup.window.calltimer();
}, false);
</script>
See it working (dont forget to allow popups)
The problem is a timing issue: window.open can return before the page has loaded, before even the player2 script has been parsed - so the function object doesn't exist yet.
Of course IE, and perhaps Edge, waits until after the child page has loaded before returning from window.open, so you can call child functions immediately. Adding a load event listener in IE actually won't work - load will have fired before you try to listen for it.
A workaround that doesn't care about timing in different browsers is to:
open the child window and record a reference to its window object.
in the child window, call a function in the opening window from the load event. This is a signal to the parent that the child is ready.
After receiving the signal from the child, the parent can proceed to call script in the child window.
Testing in the parent window:
var Popup;
function test1() {
Popup = window.open("player2.php", "bpPopup", 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=420,height=300,left = 490,top = 262');
}
function player2Ready() {
setTimeout(test2,0);
}
function test2() {
Popup.focus();
Popup.calltimer();
}
where test1 is called from a click event:
<span onclick="test1()">test</span>
The player2Ready function uses a timeout to call test2 to decouple code execution between child and parent windows for the test.
In the child (player2)
function calltimer()
{
alert('timer 2 called');
}
window.onload = function() { opener.player2Ready()};
Related
I have a window example.com/welcome.php.
Using window.open(abcd.php,"mywindow","...") I open abcd.php in new window.
By using window.close() from abcd.php. I close abcd.php. How can I trigger some action in welcome.php when abcd.php closed,
You can use onunload event attached to the opened window;
var w = open('stackoverflow.com');
w.onunload = (ev) => {
console.log('unload', ev);
};
//w.close();
Update
Set unload even inside load event to prevent from unnecessary firing unload on window open, witch happen to me in chrome at least.
var w = open('https://stackoverflow.com/users/8424614/unnamedxaer');
w.onload = () => {
w.onunload = (ev) => {
console.log('unload', ev);
};
};
Update 2
The urls have to be in the same domain to work, otherwise you will get an error when trying to attach event to opened window (w) (set debugger in the line with onunload), they also must be served from same kind of server - not accessed like files when the url in browser looks like this c:/my-site/welcome.php.
Here is working example. Open CodeSandbox's console located at the bottom of the window below the browser section to see output.
I have a small application that opens a new popup. I store the window in a variable:
popup = window.open("sites/display.html", "_blank");
After that I add a beforeunload Eventlistener:
$(popup).on('beforeunload', function(){
// Do something
});
I then later reload the window with a button:
popup.location = popup.location;
After that if I close the window the Event beforeunload isn't fired anymore. I think it has something to do with the reload because if I dont reload the page everything works fine.
How can I fix this so the event is fired everytime the window closes?
Exact code I use:
function startClock(allowRestart) {
saveSettings(allowRestart);
if ($("#separated-display").is(":checked")) {
// Separated mode activated
if (popup == undefined) {
openPopup();
} else {
if (popup.closed) {
openPopup();
}else{
popup.location.reload();
}
}
} else {
// Separated mode deactivated
if (popup != null && popup.closed == false) {
$(popup).unbind();
popup.close();
}
window.location = "sites/display.html"; // Open the clock in same window
}
}
function openPopup(){
// Open new popup window
popup = window.open("sites/display.html", "_blank");
// TO-DO: Fix event not fired after 1. window reload 2. window close
popup.addEventListener('beforeunload', function(){
console.log("unload");
});
}
As you're trying to access the same origin (with the relative path) window using window.open(), Access error shouldn't be displayed.
popup = window.open("/sites/display.html", "_blank")
popup variable would refer to the newly created window which is a thin wrapper representing a WindowProxy object, which indeed has all features of window available.
When the page reloads everything is set to default, and the window loses its properties set before. Therefore, the unload event attached earlier is not anymore attached. This would happen for other events as well.
Hence the problem here that the event is being attached to the popup window just once on opening the popup, which is reset on page reload. The best way to go forward would be to add the unload event in the js file which loads specifically on sites/display.html page. There, every time when sites/display.html page loads you could access the new window object and attach events in window.load / document.ready (according to your use case).
You won't able to attach the event to pop up before or after invoking page reload as you're doing it currently as, the property would be reset if you try setting it before/after page reload as it might be executed asynchronously.
NOTE:
You should rather use the reload() function exposed by window.location instead of updating the location property. As updating the property doesn't skip browser cache.
popup.location.reload()
The support for window.open is unknown for most browsers, though I was able to use it on Chrome 84.
The following code produces a javascript popup when a page is loaded and then closes the popup window when the parent window is closed.
<script language="JavaScript">
var player;
function load() {
player = window.open('http://www.google.com','player','height=320,width=320,scrollbars,resizable');
}
function unload() {
player.close();
}
window.onload = load;
window.onunload = unload;
</script>
This is working fine, however it closes the popup window when switching pages on the site. Is there any way this can be altered to keep the popup window until the actual URL/Site window is closed?
I think you have to check the status of the parent window from the child, instead of vice-versa.
This code has not been tested, but I'm taking a stab at the concept:
window.opener.onunload =
setTimeout(
function(){
if (!window.opener) self.close();
}, 1000);
Short answer is NO, the only way to hook into the event that closes the window is onunload, which fires when the document is unloaded (like when you navigate to another page).
Maybe you could check window.opener on the popup (with a timer, or onfocus), to check if the window that originated the popup still exists, then close the popup if it doesn't.
This may help you:
<script language="Javascript">
var player;
function load() {
player = window.open('http://www.google.com','player','height=320,width=320,scrollbars,resizable');
}
function unload() {
if (!(window.location.equals('http://yourSiteName.com'))) {
player.close();
}
}
window.onload = load();
window.onunload = unload();
</script>
I'm developing a Firefox extension and have the following code:
function initialize() {
// For accessing browser window from sidebar code.
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow);
var gBrowser = mainWindow.gBrowser;
gBrowser.onload = function() {
alert('loaded');
};
}
When I open the extension (a sidebar) and proceed to open a new tab within the Firefox window, there are three alert boxes.
When I refresh a page, there are two alert boxes.
When a page finishes loading, there is only one alert box.
When I change tabs, an alert is fired.
I use .onload rather than DOMContentLoaded or readystatechange as I need to wait until all other javascript has finished loading on a page before I run mine.
Any ideas as to why multiple events are being triggered (and for things that the event shouldn't be triggered for)?
SOLUTION
Following from MatrixFrog's suggestion, here is the solution I came to:
function initialize() {
// For accessing browser window from sidebar code.
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow);
var gBrowser = mainWindow.gBrowser;
if (gBrowser.addEventListener) {
gBrowser.addEventListener("load",pageLoaded,true);
}
}
function pageLoaded(aEvent) {
if ((aEvent.originalTarget.nodeName == '#document') &&
(aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec))
{
alert('loaded');
}
}
aEvent.originalTarget.nodeName == '#document' checks that the page is loaded and not favicons.
(aEvent.originalTarget.defaultView.location.href == gBrowser.currentURI.spec)) checks that the element that fired the event is the page in the tab, and not one of its IFRAMEs
gBrowser.onload would only fire for xul-image and not for #document so it was replaced with gBrowser.addEventListener("load",pageLoaded,true);
If you want to avoid firing the event for new blank tabs, make sure gBrowser.currentURI.spec != "about:blank"
From https://developer.mozilla.org/en/Code_snippets/On_page_load
Current Firefox trunk nightlies will fire the onPageLoad function for not only documents, but xul:images (favicons in tabbrowser). If you only want to handle documents, ensure aEvent.originalTarget.nodeName == "#document"
If you're still seeing extraneous 'load' events firing, you may want to inspect the event target to figure out what's being loaded, and use similar logic to avoid calling your extension's logic in certain specific cases.
We currently have two asp.net 2.x web applications and we need to perform the following functionality:
From one application, we want to auto-login to the other web application automatically in a new tab; using the same browser instance/window.
So the process is:
Open New Window/Tab With Second System URL/Login Page
Wait For Popup Window/Tab Page To Load (DOM Ready?)
OnPopupDomReady
{
Get Usename, Password, PIN Controls (jQuery Selectors) and Populate In Code Then Click Login Button (All Programmatically).
}
I am currently using JavaScript to Open the window as follows:
<script type="text/javascript">
$(document).ready(function () {
$('a[rel="external"]').click(function ()
{
window.open($(this).attr('href'));
return false;
});
});
</script>
I would like to use jQuery chaining functionality if possible to extent the method above so that I can attach a DOM Ready event to the popped up page and then use that event to call a method on the code behind of the popped up page to automatically login. Something similar to this (Note: The following code sample does not work, it is here to try and help illustrate what we are trying to achieve)...
<script type="text/javascript">
$(document).ready(function () {
$('a[rel="external"]').click(function () {
window.open($(this).attr('href').ready(function ()
{
// Use JavaScript (Pref. jQuery Partial Control Name Selectors) To Populate Username/Password TextBoxes & Click Login Button.
})
});
});
</script>
Our architecture is as follows:
We have the source for both products (ASP.NET WebSite[s]) and they are run under different app. pools in IIS.
When you open a window with window.open, the new window gets a property called window.opener which references the parent window. So code in your child window can call functions in the parent window, for instance:
In Window A:
// Declared at global scope => ends up as property on `window`
function phoneHome(str) {
alert(str);
}
In Window B (the child window):
$.ready(function() {
if (window.opener && window.opener.phoneHome) {
window.opener.phoneHome("Hi, Ma!");
}
});
(Using $.ready in the child window requires that the child window have jQuery loaded.)
In the above all I've done is have the child window trigger a function in the parent window with a message, but of course the function call can carry any data you want it to.