javascript alert on parent page when child popup closes - javascript

I am using javascript window.open method to open lets say http://www.google.com [its always going to be some external url]
I have stored the reference of the window object in a variable, the problem is that variable never gets null on the parent page and I am not able to alert the user that the pop up has been closed.
Here's the code
var winFB;
var winTWt;
var counterFB = 0;
var counterTWT = 0;
var timerFB;
function openFB() {
if (counterFB == 0) {
winFB = window.open("http://www.google.com");
counterFB = 1;
}
if (counterFB > 0) {
alert(winFB);
if (winFB == null) {
counterFB = 0;
clearTimeout(timerFB);
alert("Window Closed");
}
}
timerFB= setTimeout("openFB()", 1000);
}
I can not put any javascript code on the pop up/child window.
Hope someone can help me on this

The window variable doesn't get nulled out when it's closed, however its .closed property is true, so just change your check to be for that property, like this:
var winFB;
var winTWt;
var counterFB = 0;
var counterTWT = 0;
var timerFB;
function openFB() {
if (counterFB == 0) {
winFB = window.open("http://www.google.com");
counterFB = 1;
}
if (counterFB > 0) {
if (winFB.closed) {
counterFB = 0;
clearTimeout(timerFB);
alert("Window Closed");
}
}
timerFB = setTimeout(openFB, 1000);
}
Also note the setTimeout() change, pass a function in whenever possible (almost always) rather than a string, you'll have a lot less problems with scoping.

//in the parent
winFB = window.open("http://www.google.com");
//in the child window you can access
var _parent = window.opener.document;
//also use the onunload event in the child window
onunload="doSomething()"
hope this gives you some direction..

Related

Detect URL if it is already opened and throw pop-up : HTML+JS [duplicate]

I want to check with JavaScript if the user has already opened my website in another tab in their browser.
It seems I cannot do that with pagevisibility...
The only way I see is to use WebSocket based on a session cookie, and check if the client has more than one socket. But by this way, from current tab, I have to ask my server if this user has a tab opened right next to their current browser tab. It is a little far-fetched!
Maybe with localstorage?
The shorter version with localStorage and Storage listener
<script type="text/javascript">
// Broadcast that you're opening a page.
localStorage.openpages = Date.now();
var onLocalStorageEvent = function(e){
if(e.key == "openpages"){
// Listen if anybody else is opening the same page!
localStorage.page_available = Date.now();
}
if(e.key == "page_available"){
alert("One more page already open");
}
};
window.addEventListener('storage', onLocalStorageEvent, false);
</script>
Update:
Works on page crash as well.
Stimulate page crash in chrome: chrome://inducebrowsercrashforrealz
Live demo
Using local storage I created a simple demo that should accomplish what your looking to do. Basically, it simply maintains a count of currently opened windows. When the window is closed the unload events fire and remove it from the total window count.
When you first look at it, you may think there's more going on than there really is. Most of it was a shotty attempt to add logic into who was the "main" window, and who should take over as the "main" window as you closed children. (Hence the setTimeout calls to recheck if it should be promoted to a main window) After some head scratching, I decided it would take too much time to implement and was outside the scope of this question. However, if you have two windows open (Main, and Child) and you close the Main, the child will be promoted to a main.
For the most part you should be able to get the general idea of whats going on and use it for your own implementation.
See it all in action here:
http://jsbin.com/mipanuro/1/edit
Oh yeah, to actually see it in action... Open the link in multiple windows. :)
Update:
I've made the necessary changes to have the the local storage maintain the "main" window. As you close tabs child windows can then become promoted to a main window. There are two ways to control the "main" window state through a parameter passed to the constructor of WindowStateManager. This implementation is much nicer than my previous attempt.
JavaScript:
// noprotect
var statusWindow = document.getElementById('status');
(function (win)
{
//Private variables
var _LOCALSTORAGE_KEY = 'WINDOW_VALIDATION';
var RECHECK_WINDOW_DELAY_MS = 100;
var _initialized = false;
var _isMainWindow = false;
var _unloaded = false;
var _windowArray;
var _windowId;
var _isNewWindowPromotedToMain = false;
var _onWindowUpdated;
function WindowStateManager(isNewWindowPromotedToMain, onWindowUpdated)
{
//this.resetWindows();
_onWindowUpdated = onWindowUpdated;
_isNewWindowPromotedToMain = isNewWindowPromotedToMain;
_windowId = Date.now().toString();
bindUnload();
determineWindowState.call(this);
_initialized = true;
_onWindowUpdated.call(this);
}
//Determine the state of the window
//If its a main or child window
function determineWindowState()
{
var self = this;
var _previousState = _isMainWindow;
_windowArray = localStorage.getItem(_LOCALSTORAGE_KEY);
if (_windowArray === null || _windowArray === "NaN")
{
_windowArray = [];
}
else
{
_windowArray = JSON.parse(_windowArray);
}
if (_initialized)
{
//Determine if this window should be promoted
if (_windowArray.length <= 1 ||
(_isNewWindowPromotedToMain ? _windowArray[_windowArray.length - 1] : _windowArray[0]) === _windowId)
{
_isMainWindow = true;
}
else
{
_isMainWindow = false;
}
}
else
{
if (_windowArray.length === 0)
{
_isMainWindow = true;
_windowArray[0] = _windowId;
localStorage.setItem(_LOCALSTORAGE_KEY, JSON.stringify(_windowArray));
}
else
{
_isMainWindow = false;
_windowArray.push(_windowId);
localStorage.setItem(_LOCALSTORAGE_KEY, JSON.stringify(_windowArray));
}
}
//If the window state has been updated invoke callback
if (_previousState !== _isMainWindow)
{
_onWindowUpdated.call(this);
}
//Perform a recheck of the window on a delay
setTimeout(function()
{
determineWindowState.call(self);
}, RECHECK_WINDOW_DELAY_MS);
}
//Remove the window from the global count
function removeWindow()
{
var __windowArray = JSON.parse(localStorage.getItem(_LOCALSTORAGE_KEY));
for (var i = 0, length = __windowArray.length; i < length; i++)
{
if (__windowArray[i] === _windowId)
{
__windowArray.splice(i, 1);
break;
}
}
//Update the local storage with the new array
localStorage.setItem(_LOCALSTORAGE_KEY, JSON.stringify(__windowArray));
}
//Bind unloading events
function bindUnload()
{
win.addEventListener('beforeunload', function ()
{
if (!_unloaded)
{
removeWindow();
}
});
win.addEventListener('unload', function ()
{
if (!_unloaded)
{
removeWindow();
}
});
}
WindowStateManager.prototype.isMainWindow = function ()
{
return _isMainWindow;
};
WindowStateManager.prototype.resetWindows = function ()
{
localStorage.removeItem(_LOCALSTORAGE_KEY);
};
win.WindowStateManager = WindowStateManager;
})(window);
var WindowStateManager = new WindowStateManager(false, windowUpdated);
function windowUpdated()
{
//"this" is a reference to the WindowStateManager
statusWindow.className = (this.isMainWindow() ? 'main' : 'child');
}
//Resets the count in case something goes wrong in code
//WindowStateManager.resetWindows()
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id='status'>
<span class='mainWindow'>Main Window</span>
<span class='childWindow'>Child Window</span>
</div>
</body>
</html>
CSS:
#status
{
display:table;
width:100%;
height:500px;
border:1px solid black;
}
span
{
vertical-align:middle;
text-align:center;
margin:0 auto;
font-size:50px;
font-family:arial;
color:#ba3fa3;
display:none;
}
#status.main .mainWindow,
#status.child .childWindow
{
display:table-cell;
}
.mainWindow
{
background-color:#22d86e;
}
.childWindow
{
background-color:#70aeff;
}
(2021) You can use BroadcastChannel to communicate between tabs of the same origin.
For example, put the following at the top level of your js code, then test by opening 2 tabs:
const bc = new BroadcastChannel("my-awesome-site");
bc.onmessage = (event) => {
if (event.data === `Am I the first?`) {
bc.postMessage(`No you're not.`);
alert(`Another tab of this site just got opened`);
}
if (event.data === `No you're not.`) {
alert(`An instance of this site is already running`);
}
};
bc.postMessage(`Am I the first?`);
I know it is late, but maybe help someone
This snippet of code, will detect how many tabs are open and how many are active (visible) and if none of tabs is active, it will choose last opened tab, as active one.
This code will handle windows/tab crash too and it will refresh the count at crash.
Because localStorage is not supported on Stack Overflow currently, please test here.
<html>
<body>
Open in several tabs or windows
<div id="holder_element"></div>
<script type="text/javascript">
//localStorage.clear();
manage_crash();
//Create a windows ID for each windows that is oppened
var current_window_id = Date.now() + "";//convert to string
var time_period = 3000;//ms
//Check to see if PageVisibility API is supported or not
var PV_API = page_visibility_API_check();
/************************
** PAGE VISIBILITY API **
*************************/
function page_visibility_API_check ()
{
var page_visibility_API = false;
var visibility_change_handler = false;
if ('hidden' in document)
{
page_visibility_API = 'hidden';
visibility_change_handler = 'visibilitychange';
}
else
{
var prefixes = ['webkit','moz','ms','o'];
//loop over all the known prefixes
for (var i = 0; i < prefixes.length; i++){
if ((prefixes[i] + 'Hidden') in document)
{
page_visibility_API = prefixes[i] + 'Hidden';
visibility_change_handler = prefixes[i] + 'visibilitychange';
}
}
}
if (!page_visibility_API)
{
//PageVisibility API is not supported in this device
return page_visibility_API;
}
return {"hidden": page_visibility_API, "handler": visibility_change_handler};
}
if (PV_API)
{
document.addEventListener(PV_API.handler, function(){
//console.log("current_window_id", current_window_id, "document[PV_API.hidden]", document[PV_API.hidden]);
if (document[PV_API.hidden])
{
//windows is hidden now
remove_from_active_windows(current_window_id);
//skip_once = true;
}
else
{
//windows is visible now
//add_to_active_windows(current_window_id);
//skip_once = false;
check_current_window_status ();
}
}, false);
}
/********************************************
** ADD CURRENT WINDOW TO main_windows LIST **
*********************************************/
add_to_main_windows_list(current_window_id);
//update active_window to current window
localStorage.active_window = current_window_id;
/**************************************************************************
** REMOVE CURRENT WINDOWS FROM THE main_windows LIST ON CLOSE OR REFRESH **
***************************************************************************/
window.addEventListener('beforeunload', function ()
{
remove_from_main_windows_list(current_window_id);
});
/*****************************
** ADD TO main_windows LIST **
******************************/
function add_to_main_windows_list(window_id)
{
var temp_main_windows_list = get_main_windows_list();
var index = temp_main_windows_list.indexOf(window_id);
if (index < 0)
{
//this windows is not in the list currently
temp_main_windows_list.push(window_id);
}
localStorage.main_windows = temp_main_windows_list.join(",");
return temp_main_windows_list;
}
/**************************
** GET main_windows LIST **
***************************/
function get_main_windows_list()
{
var temp_main_windows_list = [];
if (localStorage.main_windows)
{
temp_main_windows_list = (localStorage.main_windows).split(",");
}
return temp_main_windows_list;
}
/**********************************************
** REMOVE WINDOWS FROM THE main_windows LIST **
***********************************************/
function remove_from_main_windows_list(window_id)
{
var temp_main_windows_list = [];
if (localStorage.main_windows)
{
temp_main_windows_list = (localStorage.main_windows).split(",");
}
var index = temp_main_windows_list.indexOf(window_id);
if (index > -1) {
temp_main_windows_list.splice(index, 1);
}
localStorage.main_windows = temp_main_windows_list.join(",");
//remove from active windows too
remove_from_active_windows(window_id);
return temp_main_windows_list;
}
/**************************
** GET active_windows LIST **
***************************/
function get_active_windows_list()
{
var temp_active_windows_list = [];
if (localStorage.actived_windows)
{
temp_active_windows_list = (localStorage.actived_windows).split(",");
}
return temp_active_windows_list;
}
/*************************************
** REMOVE FROM actived_windows LIST **
**************************************/
function remove_from_active_windows(window_id)
{
var temp_active_windows_list = get_active_windows_list();
var index = temp_active_windows_list.indexOf(window_id);
if (index > -1) {
temp_active_windows_list.splice(index, 1);
}
localStorage.actived_windows = temp_active_windows_list.join(",");
return temp_active_windows_list;
}
/********************************
** ADD TO actived_windows LIST **
*********************************/
function add_to_active_windows(window_id)
{
var temp_active_windows_list = get_active_windows_list();
var index = temp_active_windows_list.indexOf(window_id);
if (index < 0)
{
//this windows is not in active list currently
temp_active_windows_list.push(window_id);
}
localStorage.actived_windows = temp_active_windows_list.join(",");
return temp_active_windows_list;
}
/*****************
** MANAGE CRASH **
******************/
//If the last update didn't happened recently (more than time_period*2)
//we will clear saved localStorage's data and reload the page
function manage_crash()
{
if (localStorage.last_update)
{
if (parseInt(localStorage.last_update) + (time_period * 2) < Date.now())
{
//seems a crash came! who knows!?
//localStorage.clear();
localStorage.removeItem('main_windows');
localStorage.removeItem('actived_windows');
localStorage.removeItem('active_window');
localStorage.removeItem('last_update');
location.reload();
}
}
}
/********************************
** CHECK CURRENT WINDOW STATUS **
*********************************/
function check_current_window_status(test)
{
manage_crash();
if (PV_API)
{
var active_status = "Inactive";
var windows_list = get_main_windows_list();
var active_windows_list = get_active_windows_list();
if (windows_list.indexOf(localStorage.active_window) < 0)
{
//last actived windows is not alive anymore!
//remove_from_main_windows_list(localStorage.active_window);
//set the last added window, as active_window
localStorage.active_window = windows_list[windows_list.length - 1];
}
if (! document[PV_API.hidden])
{
//Window's page is visible
localStorage.active_window = current_window_id;
}
if (localStorage.active_window == current_window_id)
{
active_status = "Active";
}
if (active_status == "Active")
{
active_windows_list = add_to_active_windows(current_window_id);
}
else
{
active_windows_list = remove_from_active_windows(current_window_id);
}
console.log(test, active_windows_list);
var element_holder = document.getElementById("holder_element");
element_holder.insertAdjacentHTML("afterbegin", "<div>"+element_holder.childElementCount+") Current Windows is "+ active_status +" "+active_windows_list.length+" window(s) is visible and active of "+ windows_list.length +" windows</div>");
}
else
{
console.log("PageVisibility API is not supported :(");
//our INACTIVE pages, will remain INACTIVE forever, you need to make some action in this case!
}
localStorage.last_update = Date.now();
}
//check storage continuously
setInterval(function(){
check_current_window_status ();
}, time_period);
//initial check
check_current_window_status ();
</script>
</body>
</html>

Using JQuery on a window reference?

Can you use JQuery on a window reference? I have tried the following with no luck.
function GetDiPSWindow() {
var DiPSURL = "/DiPS/index";
var DiPSWindow = window.open("", "DiPS", "toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=520,height=875");
if (DiPSWindow.location.href === "about:blank") {
DiPSWindow.location = DiPSURL;
}
return DiPSWindow;
}
function AddRecipient(field, nameId) {
// Get window
var win = GetDiPSWindow();
// Attempt 1
$(win.document).ready(function () {
var input = win.document.getElementById(field + "_Input");
input.value = nameId;
});
// Attempt 2
$(win).ready(function () {
var input = win.document.getElementById(field + "_Input");
input.value = nameId;
});
// Attempt 3
$(win).load(function () {
var input = win.document.getElementById(field + "_Input");
input.value = nameId;
});
}
Am I making a simple mistake?
EDIT For some reason, win.document.readyState is "complete". Not sure if that makes a difference.
I have also tried:
View contains:
<script>var CallbackFunction = function() {}; // Placeholder</script>
The method:
function AddRecipient(field, nameId) {
var DiPSURL = "/DiPS/index";
if (deliveryChannel === undefined) {
deliveryChannel = 0;
}
var DiPSWindow = GetDiPSWindow();
if (DiPSWindow.location.href === "about:blank") {
DiPSWindow.location = DiPSURL;
DiPSWindow.onload = function () { DiPSWindow.CallbackFunction = AddRecipient(field, nameId) }
} else {
var input = DiPSWindow.document.getElementById(field + "_Input");
input.value = input.value + nameId;
var event = new Event('change');
input.dispatchEvent(event);
}
}
The answer is.... kinda. it depends on what you are doing.
You can use jquery on the parent page to interact with a page within an iframe, however, anything that requires working with the iframe's document object may not work properly because jQuery keeps a reference of the document it was included on and uses it in various places, including when using document ready handlers. So, you can't bind to the document ready handler of the iframe, however you can bind other event handlers, and you can listen for the iframe's load event to know when it is absolutely safe to interact with it's document.
It would be easier though to just include jquery within the iframe itself and use it instead. It should be cached anyway, so there's no real detriment to performance by doing so.

how scroll right popup window

I`m using this function to open popup windows in my site.
I want to scroll right (It is RTL) the window content, but it isnt working:
popupWins[name].scrollRight += 1000;
Any ideas?
popupWins = new Array();
function windowOpener(url, name, args) {
/*******************************
the popupWins array stores an object reference for
each separate window that is called, based upon
the name attribute that is supplied as an argument
*******************************/
if ( typeof( popupWins[name] ) != "object" ){
popupWins[name] = window.open(url,name,args);
} else {
if (!popupWins[name].closed){
popupWins[name].location.href = url;
} else {
popupWins[name] = window.open(url, name,args);
}
}
popupWins[name].scrollRight += 1000;
popupWins[name].focus();
}
Try this code
popupWins[name].document.body.scrollLeft += 1000;

(Javascript) Script won't count just once, perhaps not recognizing variable?

I'm sure this is a super easy fix and I just can't see it..
I have a play button and I only want it to write to database (inc playcount) only when it's clicked the first time.
Any idea why this doesn't work? This result counts every click, and if I do if countonce = 0 and declare at beginning as 0 it won't count any clicks. Am I misunderstanding javascript?
<div id="left-05-play_">
<script type="text/javascript">
var currsong = 1;
var playcountadd = document.getElementById('left-05-play_');
playcountadd.onclick = function() {
if (countonce != 1) {
$.post( "php/songadd.php", { addsong: "1", } );
var countonce = 1;
} }
</script>
</div>
Thank-you for taking the time to read this question.
This should do the trick.
var currsong = 1;
var songadded = false;
var playcountadd = document.getElementById('left-05-play_');
playcountadd.onclick = function() {
if (!songadded) {
$.post( "php/songadd.php", { addsong: "1", } );
songadded = true;
}
}
Changed countonce to songadded
Moved songadded out of onclick function
Changed songadded to boolean logic
Check whether songadded=false before proceeding with AJAX post

close multiple modal form window using jquery

I'm currently working on a web-app in which a window is there, within which, on clicking a button a new window is created using "window.showModalDialog" function. On new window there is a link, on clicking a link a new window is created using "window.showModalDialog".
Now, the requirement is, on timeout in the child window, i want to close these windows that was created.
I tried using Window.close() function within the setTimeOut function but it only closes the top most window. please help me on this issue. Jquery solution is also welcome.
var sessionTimeout = 2;
var warningTime = 0;
var thisWarningTimer = null;
var TimeOutTimer = "";
var sDisconnectURL = "SMTime";
function startTimeoutTimer()
{
sFlag="Y";
thisWarningTimer = setInterval("popupAsk()", (sessionTimeout) * 60000);
refreshSession();
}
function refreshSession()
{
warningTime = 1;
ClearTimer();
}
function startTimeOut()
{
var TimeOutTimer = setInterval("popupAsk()", (sessionTimeout) * 60000);
}
function ClearTimer()
{
clearInterval(TimeOutTimer);
startTimeOut();
}
function popupAsk()
{
alert("Session Timeout");
location.href="SMTime/Disconnect.jsp";
}

Categories

Resources