PostMessage - Surface from Iframe to Parent - javascript

I have a website that contains an iframe. I want to track which button the user clicks inside the iframe and surface that information to the parent window. I looked into HTML5 PostMessage, but am unsure how I would tell the iframe where the parent is (line 3 in iframe.html). Do note that the parent and iframe have the same domain and protocol.
iframe.html
<script type="text/javascript">
var domain = window.location.protocol + '//' + window.location.hostname;
var parent = document.getElementById('parent').contentWindow; //what to do?
$('div').click( function() {
var message = $(this).text();
parent.postMessage(message,domain);
});
</script>
<div id="a">A</div>
<div id="b">B</div>
<div id="c">C</div>
parent.html
<script type="text/javascript">
window.addEventListener('message', function(event) {
if(event.origin !== window.location.protocol + '//' + window.location.hostname;) {
return;
}
$('.message').html(event.data);
},false);
</script>
<div>
You have clicked on <span class="message"></span>
</div>
<iframe src="/iframe.html"></iframe>

I'm not sure how to do it in jQuery, however, here is a native way to communicate between parent and child frames in JavaScript.
The key code being:
var div = top.document.getElementById("topDiv");
Where top is the parent frame.
Parent.html
<!DOCTYPE html>
<html>
<head>
<title>Parent</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<script>
function message() {
var child = document.getElementById("childFrame"),
div = child.contentWindow.document.getElementById("childDiv");
div.innerHTML = "TEXT";
}
function main() {
document.getElementById("messenger").addEventListener("click", function() {
message();
});
}
window.onload = main;
</script>
</head>
<body>
<iframe id="childFrame" src="child.html"></iframe>
<button id="messenger">Click Me</button>
<div id="topDiv"></div>
</body>
</html>
Child.html
<!DOCTYPE html>
<html>
<head>
<title>Child</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<script>
function message() {
var div = top.document.getElementById("topDiv");
div.innerHTML = "TEXT";
}
function main() {
document.getElementById("messenger").addEventListener("click", function() {
message();
});
}
window.onload = main;
</script>
</head>
<body>
<div id="childDiv"></div>
<button id="messenger">Click Me</button>
</body>
</html>

Related

A text is displayed only right after my javascript is triggered

I wrote javascript codes.
By clicking the button, the child window pops up and displays a text sent from the parent window using a postMessage function.
My code could sent a text to the child window, but there's no text displayed.
The text is displayed only when I keep clicking the button. I don't want the text to disappear.
I think my code is overridden by a blank script or something, though I don't write any other codes except for below.
Do you have any solution for this?
the parent window html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Parent Window</title>
</head>
<body>
<input type="button" value="TEST_BUTTON" id="testButton">
<script>
var testButton = document.getElementById('testButton');
testButton.addEventListener('click', function(event) {
event.preventDefault();
var newWindow = window.open('./child_window.html', 'popupWindow', 'width=400,height=300');
newWindow.postMessage('this is a content from the parent window.', '*');
return false;
},false);
</script>
</body>
</html>
the child window html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Pop Up Window</title>
</head>
<body>
<h1 id="mainText"></h1>
<script type="text/javascript">
var mainText = document.getElementById('mainText');
window.addEventListener('message', function(event) {
console.log(event.data);
this.mainText.innerText = event.data;
}, false)
</script>
</body>
</html>
I ended this up using localStorage instead.

How to reload page without losing any inserted (div) data

i have multiple tags, which is set as editable (contentEditable="true"). is there any way to store contents in divs before load and paste the same after reload or any alternative way to do this?. I am very new in the programming field
<div contentEditable="true" id="main" key="main" class="main" >
<div contentEditable="true" id="div1" onfocusout="myFunction()"><p>sample para</p></div>
<div contentEditable="true" id="div2" onfocusout="myFunction()"><p>sample para</p></div>
</div >
window.onload = function()
{
var a = sessionStorage.getItem('main');
//alert(a);
document.getElementById("main").value = a;
}
window.onbeforeunload = function() {
sessionStorage.setItem("main", $('#main').val());
}
I tried this, but it is only for forms with known input field
My body html looks like
<body>
<div>Math in TeX notation</div>
<div contentEditable="true" id="main" key="main" class="main" >
<div contentEditable="true" id="div1" onfocusout="myFunction()"><p>sample para</p></div>
<div contentEditable="true" id="div2" onfocusout="myFunction()"><p>sample para</p></div>
</div>
</body>
You can save any data to session storage and use it later with JavaScript:
window.onload = function () {
const content = sessionStorage.getItem('main');
if (content) {
document.getElementById("main").innerHTML = content;
}
}
window.onbeforeunload = function () {
sessionStorage.setItem("main", document.getElementById("main").innerHTML);
}
I hacked this together, it works for me (using Firefox), i tested it:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="memo-pad">
<pre id="memo" contenteditable="true" onkeyup="storeUserMemo(this.id);"></pre>
</div>
<script>
function storeUserMemo(id) {
let memo = document.getElementById("memo").innerHTML;
localStorage.setItem("userMemo", memo);
}
function getUserMemo() {
let memo;
if (localStorage.getItem("userMemo")) {
memo = localStorage.getItem("userMemo");
} else {
memo = "Please write something here!";
}
document.getElementById("memo").innerHTML = memo;
}
function clearLocal() {
localStorage.clear();
document.getElementById("memo").innerHTML = "Please write something here!";
}
getUserMemo();
let memo = document.getElementById("memo");
memo.addEventListener("input", function () {
console.log("Wer ändert hier sein Memo?")
});
</script>
</body>
</html>
Whatever you put in there survives the page reload now.

can't get input value in iframe page and get to parent page

I have tried the tutorial are there, but still could not work, what's wrong with my code?
Parent Page Script:
<!DOCTYPE html>
<html>
<head>
<title>Parent</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-3.1.0.slim.js"></script>
<script>
$(function() {
var money = 20000;
$("#iframe1").contents().find("#nominal").on("change keyup", function() {
var input = $(this);
// remove possible existing message
if( input.next().is("form") )
input.next().remove();
// show message
if( input.val() > money )
alert('Hello');
});
});
</script>
</head>
<body>
<iframe id="iframe1" src="iframe.html">
</iframe>
</body>
</html>
Iframe script:
<!DOCTYPE html>
<html>
<head>
<title>Iframe</title>
</head>
<body>
<input type="text" id="nominal" value="" />
</body>
</html>
please tell me what was wrong, thanks advance.
In your HTML page
<!DOCTYPE html>
<html>
<head>
<title>Parent</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-3.1.0.slim.js"></script>
<script>
var money = 20000;
function my_custom_function(input)
{
// remove possible existing message
if( input.next().is("form") ) input.next().remove();
// show message
if( input.val() > money ) alert('Hello');
}
</script>
</head>
<body>
<iframe id="iframe1" src="iframe.html">
</iframe>
</body>
</html>
In your iframe code
<!DOCTYPE html>
<html>
<head>
<title>Iframe</title>
<script>
$(function() {
$("#nominal").change("change", function() {
parent.my_custom_function($(this));
});
$("#nominal").change("keyup", function() {
parent.my_custom_function($(this));
});
});
</script>
</head>
<body>
<input type="text" id="nominal" value="" />
</body>
</html>
Hope this trick will be helpful to you.
You have two possible scenarios:
if you can modify iframe page;
if you can't.
Your problem is that when your javascript run, the content of iframe could be not available, so JQuery cannot "attach" to child controls.
If you can change your iframe code, you can add this script to your iframe page
window.onload = function() {
parent.iframeLoaded();
}
and obviously on the parent page you must change your code to
$(function() {
var money = 20000;
window.iframeLoaded = function() {
$("#iframe1").contents().find('#nominal').on('keyup', null, function(event) {
var input = $(this);
// show message
if( input.val() > money )
alert('Hello');
});
}
});
});
If you instead cannot change iframe html, you cannot bind to keyup event of controls but you can bind to iframe one, so in this case you need to bind keyup of iframe and then filter for #nominal originated event, and your code should be like this
$(function() {
var money = 20000;
$("#iframe1").contents().on('keyup', null, function(event) {
if(event.target.id === 'nominal'){
var input = $("#iframe1").contents().find('#nominal');
// show message
if( input.val() > money )
alert('Hello');
}
});
});

Override click event is not working

I am trying to override some click event on the following domain but it won't work. After clciking on call button it will open a dialog, where it has a apply button I want to go some other website when click on that button, now it opens another dialog after clicking on that button. I have used the following code to override the click event but it dose not work.
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<title>My Website</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type='text/javascript'>
/* <![CDATA[ */
var soload = {"lang":"en","dir":"LTR","cookieOptions":{"domain":".hellobrokers.com"},
"packages":{"Clock":{},
"RegularPlatform":{"settings":{"selector":"#so_container"}}
}};
/* ]]> */
</script>
<script type='text/javascript' src='//spotplatform.hellobrokers.com/SpotOptionPlugin.js?ver=4.1.1'></script>
<script type="text/javascript">SO.load(soload);
</script>
<script>(function() {
var _fbq = window._fbq || (window._fbq = []);
if (!_fbq.loaded) {
var fbds = document.createElement('script');
fbds.async = true;
fbds.src = '//connect.facebook.net/en_US/fbds.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(fbds, s);
_fbq.loaded = true;
}
})();
window._fbq = window._fbq || [];
window._fbq.push(['track', '6022904954366', {'value':'0.01','currency':'EUR'}]);
</script>
</head>
<body>
<div id="bgbanner">
<div id="index">
<div class="mainContent">
<div id="so_container">
<div align="center" class="please_wait">
<img border="0" src="img/ajax-loader.gif" alt="" /><br />
<br />
Please Wait<br />
<br />
Loading</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function() {
$('.applyApprove').unbind();
$(".applyApprove").click(function() {
window.location = 'http://www.google.com';
});
});
</script>
</body>
</html>
Instead of .unbind(), use .off('click') and it should work:
<script>
$(document).ready(function(){
$("button.applyApprove").off('click');
$("button.applyApprove").click(function(){
window.location = "http://www.google.com";
});
});
</script>
Just use $('.applyApprove') instead of $('button.applyApprove') (notice no button):
<script>
$(document).ready(function() {
$('.applyApprove').unbind();
$(".applyApprove").click(function() {
window.location = 'http://www.google.com';
});
});
</script>

How to call a javascript function in an opened child window

I have a parent html file and want the user to click something which should then open a new window (or tab) containing the (dynamically generated) contents of a div in the parent (which is hidden in the parent).
From my reading here and elsewhere something like this should work:
parent.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Parent</title>
<script src="/js/jquery-1.11.0.min.js"></script>
</head>
<body>
<div id="from">
html from parent
</div>
<div id="launcher">
launch child
</div>
<script type="text/javascript">
$("#launcher").click(function() {
var child = window.open('child.html', '_blank', '', false);
if (child) {
var html = $("#from").html();
//window.setTimeout(child.addHTML(html), 5000);
child.addHTML(html);
}
else {
alert('Please allow popups for this site');
}
});
</script>
</body>
</html>
child.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Child</title>
<script src="/js/jquery-1.11.0.min.js"></script>
</head>
<body>
<div id="to"></div>
<script type="text/javascript">
function addHTML(html) {
$('#to').html(html);
}
</script>
</body>
</html>
However, regardless of using the commented-out setTimeout (incase the child hadn't loaded yet before calling the child's function), I get this error (in Safari, similar in Chrome) immediately:
'undefined' in not a function (evaluating 'child.addHTML(html)')
What am I doing wrong? Is there a better way to achieve my goals?
The first parameter of window.setTimeout should be the function to execute.
Try this:
if (child) {
var html = $("#from").html();
window.setTimeout(function(){child.addHTML(html);}, 5000);
}
I built a small example::
http://jsfiddle.net/rt19hv7v/
if the goal is only to add the content and not to call a function u can do it this way
if (child) {
child.addEventListener('load', function () {
var html = $("#from").html();
$('#to',child.document).html(html)
});
}else {
alert('Please allow popups for this site');
}

Categories

Resources