Why my window postMessage isn't working ? Not using iframe - javascript

So I've been trying several things in my project to send cross-domain variables.
I have a button that I click, and opens a new browser tab.
$('#btn').on('click', function(e) {
var popup = window.open("other-domain.html", "_blank");
window.popup.onload = function() {
popup.postMessage(variableToSend, '*');
}
// I even tried doing this directly, without the onload
popup.postMessage(variableToSend, '*');
});
From my other domain I do this:
(function($) {
var listener = function(event) {
console.log(event.data);
}
var setupEvents = function() {
if(window.addEventListener) {
window.addEventListener("message", listener, false);
}else{
window.attachEvent("onmessage", listener);
}
}
setupEvents();
})(jQuery);
I never receive anything from my parent window, so never gets inside listener function.
Do you know what could be wrong ? Been fighting with this for 2 days already.
Thanks in advance,
ADDED:
I tried doing this from the other domain window (children)
window.parent.postMessage('Hi!', '*');
And it receives the message correctly. Looks like I'm missing something, maybe a Timeout somewhere?

Related

Angular 2+ detect closing window

i have troubles detecting a closing window after the build is done.
const newWindow = window.open(url, '_blank', options);
newWindow.onbeforeunload = () => null;
newWindow.addEventListener('beforeunload', (evt: BeforeUnloadEvent) =>
{
console.log(evt)
}
);
it works great until i do the build, there the beforeunload event does not get triggered. i also tried placing a host listener in the new window's component:
#HostListener('window:beforeunload', [ '$event' ])
beforeUnloadHander(event: BeforeUnloadEvent): void {
debugger;
}
but the same problem here. after the build is done, we don't arrive at the debugger anymore
anybody any idea what i am doing wrong? thanks for your help!
Edit Workaround
const heartBeatNewWindow = setInterval(() => {
if (newWindow.closed) {
this.canvasSettings.displayInNewWindow = false;
clearTimeout(heartBeatNewWindow);
}
}, 1500);
I had to do something similar and my approach was the following:
I created a generic catch from close event windows in the constructor of my service, them call method what handle this event. Inside this method I validate the origin of this event is the correct to execute the logic I needed. Look this example:
Inside the constructor:
if(window.addEventListener){
window.addEventListener("message", this.authService.handleMessage.bind(this), false);
}else{
(<any>window).attachEvent('onmessage', this.authService.handleMessage.bind(this));
}
And my method to handle that event:
handleMessage(event: Event) {
event.preventDefault();
const message = event as MessageEvent;
// Only trust messages from the below origin.
//
if ((message.origin !== environment.BASE_URL)) return;
const result = JSON.parse(message.data);
//Add your logic here
I Hope be helpfull.

Using postMessage() isn't being received

I'm sure it's just a problem with my syntax but I am trying to send a variable to an iframe (for colorbox to use). For the time being I am accepting any domains on both ends (just to get it to work). Here is the js for the sending page:
$(document).ready(function() {
if(window.location.hash) {
var urlimage = window.location.hash.substring(1);
targetiframe = document.getElementById('wbgallery').contentWindow;
targetiframe.postMessage(urlimage, "*");
console.log(urlimage);
}
});
And here is the receiving page:
$(document).ready(function() {
window.addEventListener('message',receiveMessage);
console.log(event);
function receiveMessage(event) {
if (origin !== "*")
return;
inbound = event.data;
console.log(inbound);
}
});
I see the console log for urlimage and can see an event but nothing for inbound. I'm using Mozilla's explanation to try and work it all out.
You're sending the message before the page in the iframe has loaded, so the message listener hasn't been established yet.
You can have the iframe send a message to the parent when it's ready, and then send the message after this.
Parent code:
$(document).ready(function() {
if (window.location.hash) {
var urlimage = window.location.hash.substring(1);
var targetiframe = document.getElementById('wbgallery').contentWindow;
$(window).on("message", function(e) {
targetiframe.postMessage(urlimage, "*");
console.log(urlimage);
});
}
});
Iframe code:
$(document).ready(function() {
$(window).on('message', function(event) {
inbound = event.data;
console.log(inbound);
});
window.parent.postMessage("ready", "*");
});

How to right click from javascript

It seems that it is not possible to emulate a right click in javascript.
I have tried to right click an element (paragraph) in an iframe like this:
html
<button onclick="popup_context_menu_in_iframe()">
popup menu
</button>
<br/><br/>
<iframe srcdoc="<p>Hello world!</p>">
</iframe>
script
function popup_context_menu_in_iframe()
{
var $element = $('iframe').contents().find('p');
var element = $element.get(0);
if (window.CustomEvent) {
element.dispatchEvent(new CustomEvent('contextmenu'));
} else if (document.createEvent) {
var ev = document.createEvent('HTMLEvents');
ev.initEvent('contextmenu', true, false);
element.dispatchEvent(ev);
} else { // Internet Explorer
element.fireEvent('oncontextmenu');
}
}
https://jsfiddle.net/sca60d64/2/
It seems like it actually is impossible to make the context menu appear so I need to find other ways.
I first headed at creating a chrome extension to add a function to the window object, callable from any script that is using some extra power to do it.
However, A chrome extension surprisingly seems to not provide me with a way of creating functions in the window object. I have not taken a look if it even gives me the power to popup the context menu.
I did not experiment a lot with chrome extensions before giving up on that.
So I need another solution.
It doesnt matter if a solution only works in google chrome or if there is no guarantee that it will stop work in the next version.
Should I hook the chrome process with a dll? Is that it?
You can call a dll by an exe file in the chrome extension through Native Messaging. I have provided a sample of Native Messaging procedure in this answer:
See the answer of this question
I hope to be useful.
This should work with this markup:
<div id="mything">
Howdy this is my thing
</div>
event handler:(disable default)
var el=document.getElementById("mything");
el.addEventListener('contextmenu', function(ev) {
ev.preventDefault();
alert('success!');
return false;
}, false);
Then when you execute this, "sucess!" alerts followed by the text changing to "Howdy this is my thing this is canceled":
EDIT event handler:(do NOT disable default)
var el=document.getElementById("mything");
el.addEventListener('contextmenu', function(ev) {
ev.preventDefault();
alert('success!');
return true;
}, true);
Then when you execute this, "sucess!" alerts followed by the text changing to "Howdy this is my thing this is NOT canceled":
function simulateRightClick() {
var event = new MouseEvent('contextmenu', {
'view': window,
'bubbles': true,
'cancelable': true
});
var cb = document.getElementById('mything');
var canceled = !cb.dispatchEvent(event);
var cbtext = cb.textContent;
if (canceled) {
// A handler called preventDefault.
console.log("canceled");
cb.textContent = cbtext + "this is canceled";
} else {
// None of the handlers called preventDefault.
cb.textContent = cbtext + "this is NOT canceled";
console.log("not canceled");
}
}
simulateRightClick();
Test it out here: https://jsfiddle.net/MarkSchultheiss/bp29s0j4/
EDIT: alternate selector:
var fcb = document.getElementById('myframe').contentWindow.document.getElementById('pid');
fcb.addEventListener('contextmenu', function(ev) {
ev.preventDefault();
alert('successFrame!');
return false;
}, false);
Given this markup:
<iframe id='myframe' srcdoc="<p id='pid'>Hello world!</p>">
</iframe>

Javascript onUnload Show offer and redirect to offer page if stays on page [duplicate]

Rewriting the question -
I am trying to make a page on which if user leave the page (either to other link/website or closing window/tab) I want to show the onbeforeunload handeler saying we have a great offer for you? and if user choose to leave the page it should do the normal propogation but if he choose to stay on the page I need him to redirect it to offer page redirection is important, no compromise. For testing lets redirect to google.com
I made a program as follows -
var stayonthis = true;
var a;
function load() {
window.onbeforeunload = function(e) {
if(stayonthis){
a = setTimeout('window.location.href="http://google.com";',100);
stayonthis = false;
return "Do you really want to leave now?";
}
else {
clearTimeout(a);
}
};
window.onunload = function(e) {
clearTimeout(a);
};
}
window.onload = load;
but the problem is that if he click on the link to yahoo.com and choose to leave the page he is not going to yahoo but to google instead :(
Help Me !! Thanks in Advance
here is the fiddle code
here how you can test because onbeforeunload does not work on iframe well
This solution works in all cases, using back browser button, setting new url in address bar or use links.
What i have found is that triggering onbeforeunload handler doesn't show the dialog attached to onbeforeunload handler.
In this case (when triggering is needed), use a confirm box to show the user message. This workaround is tested in chrome/firefox and IE (7 to 10)
http://jsfiddle.net/W3vUB/4/show
http://jsfiddle.net/W3vUB/4/
EDIT: set DEMO on codepen, apparently jsFiddle doesn't like this snippet(?!)
BTW, using bing.com due to google not allowing no more content being displayed inside iframe.
http://codepen.io/anon/pen/dYKKbZ
var a, b = false,
c = "http://bing.com";
function triggerEvent(el, type) {
if ((el[type] || false) && typeof el[type] == 'function') {
el[type](el);
}
}
$(function () {
$('a:not([href^=#])').on('click', function (e) {
e.preventDefault();
if (confirm("Do you really want to leave now?")) c = this.href;
triggerEvent(window, 'onbeforeunload');
});
});
window.onbeforeunload = function (e) {
if (b) return;
a = setTimeout(function () {
b = true;
window.location.href = c;
c = "http://bing.com";
console.log(c);
}, 500);
return "Do you really want to leave now?";
}
window.onunload = function () {
clearTimeout(a);
}
It's better to Check it local.
Check out the comments and try this: LIVE DEMO
var linkClick=false;
document.onclick = function(e)
{
linkClick = true;
var elemntTagName = e.target.tagName;
if(elemntTagName=='A')
{
e.target.getAttribute("href");
if(!confirm('Are your sure you want to leave?'))
{
window.location.href = "http://google.com";
console.log("http://google.com");
}
else
{
window.location.href = e.target.getAttribute("href");
console.log(e.target.getAttribute("href"));
}
return false;
}
}
function OnBeforeUnLoad ()
{
return "Are you sure?";
linkClick=false;
window.location.href = "http://google.com";
console.log("http://google.com");
}
And change your html code to this:
<body onbeforeunload="if(linkClick == false) {return OnBeforeUnLoad()}">
try it
</body>
After playing a while with this problem I did the following. It seems to work but it's not very reliable. The biggest issue is that the timed out function needs to bridge a large enough timespan for the browser to make a connection to the url in the link's href attribute.
jsfiddle to demonstrate. I used bing.com instead of google.com because of X-Frame-Options: SAMEORIGIN
var F = function(){}; // empty function
var offerUrl = 'http://bing.com';
var url;
var handler = function(e) {
timeout = setTimeout(function () {
console.log('location.assign');
location.assign(offerUrl);
/*
* This value makes or breaks it.
* You need enough time so the browser can make the connection to
* the clicked links href else it will still redirect to the offer url.
*/
}, 1400);
// important!
window.onbeforeunload = F;
console.info('handler');
return 'Do you wan\'t to leave now?';
};
window.onbeforeunload = handler;
Try the following, (adds a global function that checks the state all the time though).
var redirected=false;
$(window).bind('beforeunload', function(e){
if(redirected)
return;
var orgLoc=window.location.href;
$(window).bind('focus.unloadev',function(e){
if(redirected==true)
return;
$(window).unbind('focus.unloadev');
window.setTimeout(function(){
if(window.location.href!=orgLoc)
return;
console.log('redirect...');
window.location.replace('http://google.com');
},6000);
redirected=true;
});
console.log('before2');
return "okdoky2";
});
$(window).unload(function(e){console.log('unloading...');redirected=true;});
<script>
function endSession() {
// Browser or Broswer tab is closed
// Write code here
alert('Browser or Broswer tab closed');
}
</script>
<body onpagehide="endSession();">
I think you're confused about the progress of events, on before unload the page is still interacting, the return method is like a shortcut for return "confirm()", the return of the confirm however cannot be handled at all, so you can not really investigate the response of the user and decide upon it which way to go, the response is going to be immediately carried out as "yes" leave page, or "no" don't leave page...
Notice that you have already changed the source of the url to Google before you prompt user, this action, cannot be undone... unless maybe, you can setimeout to something like 5 seconds (but then if the user isn't quick enough it won't pick up his answer)
Edit: I've just made it a 5000 time lapse and it always goes to Yahoo! Never picks up the google change at all.

Set New tab/window URL in Safari Extension

I am creating a safari extension. how do I manually set the new tab/window to a URL of my choosing? I used some of logic from this post to make sure I am only taking over user created tabs/windows Safari extension: Event for a completely new tab?
I set up my new tab event listener:
safari.application.addEventListener("open", handleOpen, true);
Using this to handle the open tab/window:
function handleOpen(e) {
if (e.target instanceof SafariBrowserTab) {
e.target.addEventListener('beforeNavigate', handleBeforeNavigate, false);
setTimeout(function () {
e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false);
takeOverTab();
}, 50);
}
}
function handleBeforeNavigate(e) {
e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false);
if (e.url === null) {
takeOverTab();
}
}
function takeOverTab() {
window.location.href = "http://www.yahoo.com";
}
I am able to alert when a new tab/window is opened, but I cant for the life of my figure out how to actually browse to the url. I tried window.location.href but that doesn't seem to do anything, I still get the "top sites" page when I open a new tab.
Thanks in advance!
Change your takeOverTab function as follows:
function takeOverTab(tab) {
tab.url = "http://www.yahoo.com";
}
And modify the function call to include a reference to the tab:
takeOverTab(e.target);
Also, in your beforeNavigate handler, you should add e.preventDefault() to prevent the tab from loading whatever it was going to load:
function handleBeforeNavigate(e) {
e.target.removeEventListener('beforeNavigate', handleBeforeNavigate, false);
if (e.url === null) {
e.preventDefault();
takeOverTab();
}
}

Categories