I'm trying to determine whether a popup exists in javascript. I do know its name (passed in window.open()), but I do not have a window reference. For example consider this: I have a web page A which calls window.open('url', 'popup') and I have web page B which also wants to call window.open('url', 'popup') unless such popup exists. In this case B just focuses on popup. So web page B has no reference to popup (and it cannot have, we may assume that A and B are independent). Is there a way to do that?
You should be able to do it if you play around with your window structure.
Whenever I've come across this problem I've had a main window which always exists. Then, when calling window.open, I grab the handler that that function returns and then assign it to the main window that I know will always exist.
Then, whenever calling window.open, I go off and check main window to see if it has an open window handler for the popup window.
So, assuming you have that main window that always exists (you could always use have a window that uses a frame to display your actual content so, to your users, it'll look the same), you could do something like:
var mainWindow = window;
while(mainWindow != mainWindow.parent){
mainWindow = mainWindow.parent;
}
if(mainWindow.PopupWindow === undefined || mainWindow.PopupWindow.closed){
var handler = window.open('url', 'popup');
mainWindow.PopupWindow = handler;
}
I've always had a few problems using the closed property of the window object, so you may need to map a function to the onunload event within the popup window that just clears out the PopupWindow variable on the mainWindow, and then add that check within your if statement too.
Related
I've got a function that essentially refreshes a table, which works ok, but some of the JS functions don't run. To debug I'm trying to pass data between a popup and it's parent window. Currently I have this function:
$.fn.runFncs = function(isParent)
{
if (isParent == 1) {
window.opener.$.fn.compareDates();
window.opener.$.fn.addStatusIcon();
window.opener.$.fn.iconTooltips(1);
window.opener.$.fn.iconTooltips(2);
window.opener.console.log('test');
} else {
$.fn.compareDates();
$.fn.addStatusIcon();
$.fn.iconTooltips(1);
$.fn.iconTooltips(2);
}
};
and this gets run on an ajax success.
When I hit the button for the ajax, I get my success message etc. but no console.log in my parent window. I've been able to access the parent window before using window.opener and it seems to run ok, just not this time for some reason.
I tried research but either my query was too specific or it was simple "what is console.log" questions so a little stuck here.
Is there an alternative way I can console.log to the parent window? Maybe a document function I'm unaware of?
Thanks! :)
function log(message){
console.log(message);
}
Put that function in your parent window and call it like so. You basically need to provide a wrapper function that you can access
window.opener.log("Hi");
You cannot access directly from one window/tab to anothers's console object, but you can send messages from one window to another. The parent window would get that messages and then it would write it on the console. See this Q&A for more details:
I tried out in recent (2018 aug) Firefox, Chrome and Opera and IE11 too and window.opener.console.log works perfectly in all of them. So I think the problem were somewhere else in your code.
You could even do child.console = console in the parent window and keep console.log, but most of the browsers clear that variable between page loads, and there is no way to set it again right after the document was created, but before the scripts are executed. You can add window.console = window.opener.console to the head of the child page if you can edit that. That should do the trick too.
i am trying to save the current window in focus event to app properties like this
$.profileWin.addEventListener('focus', function(e) {
Ti.App.Properties.setObject("curwin", $.profileWin);
});
i am doing this for more than 1 window
but at focus of window i get this error
-[TiUIWindowProxy encodeWithCoder:]: unrecognized selector sent to instance 0x1ea19c00";
how do i save the the current window and have it accessed when the iPhone resumes from its suspended state
When you try to save a value in Ti.App.Properties it will simply be converted to at string of text. I'm not sure setObject will accept anything else but JSON-objects (and a Ti.UI.Window is not a JSON-object).
That being said, saving the actual Window-object might not be a good idea, as the different dependencies might have been removed from memory, when you try to reload the window.
A better approach would be to save the relevant properties of the Window (and other values that you might need to restore the current state of the Window) and the re-layout the Window once it gains focus.
I hope I did my homework well, searching the Internets for the last couple of hours and trying everything before posting here, but I'm really close to call it impossible, so this is my last resort.
I want a simple thing (but seems like hard in JavaScript):
Click button -> Open Window (using window.open)
Perform an action in the popup window and return the value to parent (opener)
But I want to achieve it in a systematic way, having a callback defined for this popup; something like:
var wnd = window.open(...)
wnd.callback = function(value) {
console.log(value);
};
I've tried defining the callback property in popup window JS code:
var callback = null;
Unfortunately, that does not work, as...
$('#action').click(function() {
console.log(callback);
});
... returns just that "null" I set initially.
I've also tried setting the callback in a parent window after window load (both thru window.onload=... and $(window).ready()), none worked.
I've also tried defining some method in child window source code to register callback internally:
function registerCallback(_callback)
{
callback = _callback; // also window.callback = _callback;
}
But with the same result.
And I don't have any more ideas. Sure, it would be simple setting the value using window.opener, but I'll loose much of a flexibility I need for this child window (actually an asset selector for DAM system).
If you have some ideas, please share them.
Thank you a million!
HTML5's postMessage comes to mind. It's designed to do exactly what you're trying to accomplish: post messages from one window and process it in another.
https://developer.mozilla.org/en/DOM/window.postMessage
The caveat is that it's a relatively new standard, so older browsers may not support this functionality.
http://caniuse.com/#feat=x-doc-messaging
It's pretty simple to use:
To send a message from the source window:
window.postMessage("message", "*");
//'*' is the target origin, and should be specified for security
To listen for messages in a target window:
window.addEventListener
("message", function(e) {
console.log(e.data); //e.data is the string message that was sent.
}, true);
After few more hours of experiments, I think, I've found a viable solution for my problem.
The point is to reference jQuery from parent window and trigger a jQuery event on this window (I'm a Mac user but I suppose, jQuery has events working cross-platform, so IE compatibility is not an issue here).
This is my code for click handler on anchor...
$(this).find('a[x-special="select-asset"]').click(function() {
var evt = jQuery.Event('assetSelect', {
url: 'this is url',
closePopup: true,
});
var _parent = window.opener;
_parent.jQuery(_parent.document).trigger(evt);
});
... and this is the code of event handler:
$(document).bind('assetSelect', function (evt) {
console.log(evt);
});
This solution is fine, if you don't need to distinguish between multiple instances of the asset selection windows (only one window will dispatch "assetSelect" event). I have not found a way to pass a kind of tag parameter to window and then pass it back in event.
Because of this, I've chosen to go along with (at the end, better and visually more pleasant) solution, Fancybox. Unfortunately, there is no way - by default - to distinguish between instances either. Therefore, I've extended Fancybox as I've described in my blog post. I'm not including the full text of blog post here, because is not the topic of this question.
URL of the blog post: http://82517.tumblr.com/post/23798369533/using-fancybox-with-iframe-as-modal-dialog-on-a-web
In my application I created an iframe in my lightbox, when I open the lightbox after it will call parent window function and close the lightbox, in the parent window function will create and update some DOMs, and then When I go to back the parent window I try to access those DOMs it will throw an exception "script5011: Can't execute code from a freed script".
I call the parent window function at the iframe like this window.parent.myFunc(arg1, arg2....), it will got an exception, I think that is an IE 9 new feature changed, because I tested in IE 6, 7, 8 and other browsers are working fine all, I not yet find a valid solution for IE 9, I hope can get an answer from here. any ideas?
The cause of this issue is that IE9 removes reference to a parent window’s object when the frame’s URL is changed subsequently and this is done to increase security.
The solution for this is to setup functions in the parent window which can modify (setters & getters) the parent window data objects. You can pass objects to the parent window's function after its serialized to a string. The best way to call the parent frame's function is by calling the following in the child frame.
window.parent.eval("resetDataObject()");
and in the parent frame write something like:
var myDataObject = [];
function resetDataObject()
{
myDataObject = [];
}
Check this post http://www.tejzpr.com/2014/10/codefix-script5011-cant-execute-code.html
I have a web app that launches an URL in other windows/tabs. I would like to check if the window/tab exists. If not, I want to create it, else I would like to pick it in the first position.
I use:
wf=window.open(address, web_form_target, 'toolbar=1,scrollbars=1,location=1,statusbar=1,menubar=1,resizable=1,width=640,height=450');
if(wf!=null)
wf.focus();
But it goes well only the first time (in IE, not in Firefox). If I create a new tab in the window, when I call window.open() nothing happens. If I close the window it recreates it but keeps it ionized.
Is there a way I can follow to obtain a good result?
Thanks in advance.
Here's some code I've used for ages that still works as far as I know. Notice that oWindow has global scope, and that I pass it to the second parameter of open as a string, not as the object itself. Then, I test to see if it's closed before trying to open again...if it's already opened, then I just give it focus:
var oWindow;
function openWindow(p_strURL) {
if(!oWindow || oWindow.closed) {
oWindow = window.open(p_strURL, "oWindow", "status, scrollbars, resizable, width=800, height=500");
if(!oWindow.opener) {
oWindow.opener = window;
}
}
else {
oWindow.location.href = p_strURL;
oWindow.focus();
}
}
Hope it helps you find a solution,
Kevin
web_form_target is the window name.
if (wf.name !== web_form_target) {
// create it
}