My requirement is that I need to call some API after close tab from browser in Javascript.
I have tried below code which almost everyone suggest, but that is not working every time. I have tried every possible way with below code:
window.onbeforeunload = function () {
callClose();
return;
};
function callClose() {
// API call
}
I need proper reliable solution for this. Can anyone help me on this, I am stuck here.
Related
I have created a project in .fla that was exporting to .swf however I now require it in HTML5 format. So I change the file conversion type and now require my ActionScript3 to be converted to JavaScript. However, This is not my strong suit.
I am currently trying:
this.stop();
this.close1_btn.addEventListener("click", function (closebtn)
{
this.gotoAndPlay(1);
});
this.store1_btn.addEventListener("click", function (store1_btn)
{
this.gotoAndPlay(11);
});
this.store2_btn.addEventListener("click", function (store2_btn)
{
this.gotoAndPlay(12);
});
this.store3_btn.addEventListener("click", function (store3_btn)
{
this.gotoAndPlay(13);
});
OVERVIEW: trying to listen to a symbol e.g close1_btn for clicks. when clicked it will link to and stop at a specified frame.
I expect a few bits to be wrong *maybe near the function () part?
Its a fairly simple map so shouldn't be too hard for someone who knows what they are looking at! Thanks so much for any help you can give!
I believe the issue is the function scope, which is a common mistake.
The addEventListener method has no implied scope, so the functions will get called on window. If you output this in your console when those buttons are clicked, you will probably see Window. To solve this, you can:
Bind your methods (docs)
Example:
this.close1_btn.addEventListener("click", function (closebtn)
{
this.gotoAndPlay(1);
}.bind(this));
Use the CreateJS on shortcut, which takes a 3rd parameter (docs)
Example:
this.close1_btn.on("click", function (closebtn)
{
this.gotoAndPlay(1);
}, this);
One important note is that if you play frame 0 again, that frame script will run again, adding another listener to each button each time, resulting in the functions called multiple times when a button is clicked. I recommend something this this:
if (!this.inited) {
// Your code
this.inited = true;
}
Thanks for your response.
I am now using the code you provided:
this.stop();
if (!this.inited) {
// Your code
this.close1_btn.addEventListener("click", function (closebtn)
{
this.gotoAndPlay(1);
}.bind(this));
this.store1_btn.addEventListener("click", function (store1btn)
{
this.gotoAndStop(11);
}.bind(this));
this.inited = true;
}
However, I get this in the output
WARNINGS:
Frame numbers in EaselJS start at 0 instead of 1. For example, this affects gotoAndStop and gotoAndPlay calls. (5)
Content with both Bitmaps and Buttons may generate local security errors in some browsers if run from the local file system.
Any further advice you could give would be appreciated...
cheers for your continued assistance!
The preview doesn't work when it opens in my browser, is this just because I haven't exported it fully and hosted it online?
So I can ignore these errors?
^^ if that's all cleared up. Do you have recommended way to export and host it on a webpage?
Thanks again buddy, appreciate it!
I am using Javascript with the window.onload and window.onbeforeunload functions.
In the onbeforeunload I want to run a code that removes an element from an existing list by iterating through the list via a method, but the method doesn't get executed.
When I use the same method in onload, everything works fine.
I think the code doesn't get executed in the onbeforeunload because the browser is already closed by then and that causes that the method doesn't get executed.
I think I need to do something Sychronous, do you guys have tips on how I can solve this?
// working
window.onload = function()
{
MethodA();
};
// not working
window.onbeforeunload = function()
{
MethodA();
};
I currently am working on a bookmarklet that opens an iframe, and sets up a communication of postMessage back and forth. That all works fine.
However, seemingly because the bookmarklet is being loaded as an anonymous function, the listeners are multiplying if I run the bookmarklet more than once on a page.
Is there some sort of way to keep track of these addEventListeners so that they don't double-up?
Do I need to define the rp_receive_message outside of the anonymous function?
Here's an example of the code:
var rp_receive_message = function (e) {
var response = e.data;
console.log("got message with "+ response);
};
if (window.addEventListener) {
window.addEventListener('message', rp_receive_message, false);
} else {
window.attachEvent('onmessage', rp_receive_message);
}
var s1 = window.document.createElement('iframe');
s1.setAttribute('src', 'http://mydomain.com/iframe.html');
s1.setAttribute('id', 'testiframe');
s1.setAttribute('width', '700');
s1.setAttribute('height', '550');
s1.setAttribute('frameBorder', '0');
s1.setAttribute('onload', 'this.contentWindow.postMessage(window.location.href, "http://mydomain.com/iframe.html");');
document.getElementById('container').appendChild(s1);
Probably this will solve the problem:
window.onmessage = rp_receive_message;
As you suggest, the code below might be enough by itself. I don't know if addEventListener and attachEvent will add the same function multiple times, but I wouldn't at all be surprised if they will. I suggest just testing it.
window.rp_receive_message = function(){...}
If you dislike either solution, you've got to set up a global variable, which hardly seems any different or greatly superior to above. The global can be a simple boolean to check if the event has been attached, or it can be a list of attached events that you update yourself. AFAIK, and I'm pretty sure, there is no native JS solution to get a list of event listeners have been attached to a particular event. Libraries such as jQuery maintain lists and let you read them; and possibly have other techniques that are elegant solutions to your general problem.
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
If this is a duplicate question I am sorry, it seems basic enough but could not find a proper answer.
The only way I have found so far to capture the browser window close event from actionscript/flash is actually to capture the event in javascript, and then use a javascript/flash data passing from the javascript callback.
Something around those lines:
window.onbeforeunload = clean_up;
function clean_up()
{
var flex = document.${application} || window.${application};
flex.myFlexFunction();
}
</SCRIPT>
and the flash part:
import flash.external.ExternalInterface;
ExternalInterface.addCallback("myFlexFunction",cleanUp);
public function cleanUp():void{
//your flash code here
}
Is this the proper way ?
Are there other alternatives ?
You can never catch the window close event from pure flash. That said, as far as I know, this is the proper way to handle this.