javascript proper way to call function - javascript

I'm not good in javascript but I find examples and usually understand it. But this is driving me crazy for the last hour. What I'm trying to do is to embed the list.php file to my mainpage.html using the IFRAME. This list.php is showing some links and when I click the link the result should be shown in another place on main page (I'm targeting some div). And those 3 functions are placed inside list.php file.
If I do this:
function autoscroll() {
window.parent.parent.scrollTo(0,0);
}
function resizeIframe(obj) {
obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px';
}
function url2div(url,target){
parent.document.getElementById(target).innerHTML = '<iframe style="width:100%;height:100%;" scrolling="no" frameborder="1" onload="javascript:resizeIframe(this); javascript:autoscroll();" src="' + url + '" />';
}
So if I call the autoscroll() function within my IFRAME like this
onload="javascript:autoscroll();"
autoscroll doesn't work (everything else is working).
But if I put it directly in IFRAME like this:
onload="javascript:window.parent.parent.scrollTo(0,0);"
then it works!
What's wrong with first approach?

It sounds like you're putting the script element in your main page, but then trying to use it in an iframe on the page. Also, you're using window.parent.parent which goes two levels up the containment hierarchy, which seems suspicious.
The iframe and the main window are two different environments. Globals (like your autoscroll) in the main page are not in scope for the iframe's code.
The iframe can access the parent window's globals, provided they're from the same origin, via the parent symbol:
parent.autoscroll();
Then use window, or window.paren, depending on whether you want to scroll the parent or its parent.
It's all about being relative to the document in which the script is included.
Since that was clear as mud: Let's assume your goal is to scroll the main window that the iframe is in:
Option 1: Put it in the iframe (probably best):
In the main window:
Nothing.
In the iframe
<script language="JavaScript">
function autoscroll() {
window.parent.scrollTo(0,0); // <== Only one `parent`, if you want the iframe's parent
}
</script>
and
onload="autoscroll();"
Or:
Option 2: Put it in the main window:
In the main window:
<script language="JavaScript">
function autoscroll() {
window.scrollTo(0,0); // <== No `parent` at all, if you want the main window
}
</script>
In the iframe:
onload="parent.autoscroll();"

Related

Write inline javascript in iframe

I have code that can be reduced to this:
<script>
function write_to_iframe(){
let nw = document.getElementById("mysrc");
let myframe = document.getElementById("myframe");
myframe.contentWindow.document.body.innerHTML = nw.innerHTML;
}
</script>
<iframe id="myframe" width="230" height="95"></iframe>
<div id="mysrc">
<script>
function hello(){
alert("hello world");
}
</script>
SayHello<br>
</div>
It writes the code in the div to the iframe. That part seems to work. However, when I click the SayHello link in the iframe I get a javascript error that the function hello() cannot be found.
What is going wrong here? And how can I declare an inline javascript function in the frame that works.
I am not interested in external javascript files or code that puts everything in the link (like onclick="javascript:alert('hi');").
I would reconsider using an iframe with innerHTML and trying to call a function in the main document from it. The support can vary in different browsers, iframes access to its parent is very limited. If both those things are on the same domain then you don't break CORS policy and you can do more but still there are better options.
If you insist on using iframe, I would consider creating an external path for it (same domain) ex. iframe/embed.html put HTML there normally, then change location after click triggered inside to iframe/embed.html#callHello. And in main document I would add eventListner to detect location change.
const iframe = document.getElementById("iframeId");
window.open("https://example.com/iframe/embed.html", "iframeId");
iframe.addEventListener("load", () => {
if (iframe.contentWindow.location.href.includes('#callHello')) {
hello();
}
});

Get all elements inside iframe tag

this is my part of code now i'm using iframe tag and loaded epub on iframe tag
then i don't know how to get all elements inside iframe tag.
jQuery(document).ready(function($) {
var tmp = $('#epub_loader iframe').contents().find('body').html();
alert(tmp);
});
<iframe id="epub_loader" href="test.epub" ></iframe>
`
Assuming both your frames are on the same domain and there is no restriction with Same Domain Policy, you can use the following code from the "parent" frame to get an element in the "child" iframe (in your case body tag).
Pseudo code, you need to actually point to your iframe DOM by id:
var html = document.getElementById('iframe').contentDocument.body.innerHTML;
Notes: In case iframe is on a different domain, you have limited access for browser security reasons.
The thing you need is to wait document will be fully loaded coz you are used iframe,then you should call ....
jQuery(document).ready(function() {
window.onload = function () { //call when iframe is fully loaded
var tmp = $('#epub_loader').contents().find('body').html();
alert(tmp);
};
});

DOM Events - Progress Indicator for Iframe location change

I am looking for a solution to show a progress indicator when an iframe page changes, but prior to the iframe loading completely.
There are 100's of pages on Stack Overflow going over the differences between jQuery ready(), JavaScript window.load, document.load, DOMContentReady, on('pageinit'...) and after reading the differences on all these various techniques I'm now a bit stuck on how to accomplish trapping the event within the iframe.
So far I have only succeeded in capturing when the iframe has changed once the DOM is built. I would like to be able to detect when a page is about to load so I could have some sort of indicator/spinner in my header.
This is what I have so far (capturing the iframe change on the onload):
.....
<iframe id="rssID" src="http://feeds.reuters.com/reuters/oddlyEnoughNews"
onload="blerg()" style="width: 800px; height:600px"/>
......
$(document).on('pageinit','#index', function(){
alert('pageinit'); //gets called on first load
});
$(document).on('pageinit','#rssID', function(){
alert('pageinit rssFeed'); //nothing happens.
});
function blerg() {
var myIframe = document.getElementById("rssID");
myIframe.onload = func;
};
function func() {
alert("changed");
}
http://jsfiddle.net/Gdxvs/
It would appear that pageinit is the correct path but I have no idea on how to trap that within an iframe. I would prefer not using jQuery, but I'm not sure that is possible without huge amounts of code.
One final: Do I need to use a die("pageinit");

Capture click event from child frame into parent frame

Right, this is weird. I have done loads of Googling and found hundreds of articles which seem to point me in the right direction, but none seem to work.
Here's the latest incarnation of what I am trying to do:
Parent Page
<html>
<head>
<script>
$('#mainWindow').ready(function () {
$('#mainWindow').contents().find('#clickThis').live('click', function () {
alert('Click detected!');
});
});
</script>
</head>
<body>
<iframe id="mainWindow" name="mainWindow" src="myMainPage.aspx" style="border: 0; position:fixed; top:0; left:0; right:0; bottom:0; width:100%; height:100%"></iframe>
<iframe src="myOtherPage.aspx"></iframe>
</body>
</html>
Framed Page (sitting in mainWindow)
<html>
' LOADS OF STUFF INCLUDING:
<li id="clickThis">Click This</li>
</html>
So obviously what I am trying to do here is to run some code in the Parent Page when a user clicks the button in the child frame.
It needs to work live so if the page in the frame changes it is still captured by the parent (this element exists on all pages which will be loaded into the frame)
I have been able to run codes across iFrames, from parent to iFrame and from iFrame to iFrame following various other searches, but running from iFrame to parent is causing issues.
The above code does nothing, and neither do any of the other options I have tried!!
*Edit should add, all files are on the same server, the cross domain issue is not a problem
This works fine for me:
$('#myframe').contents().on('click', function () {
$('#result').text('clicked');
});​
If you want to capture the events just on a part of the content document, use .contents().find(<selector>) (<selector> being e.g. 'body') instead of just .contents()
Something to watch out for: All of your pages must exist under the same document.domain or the JavaScript calls will fail. You will see this surfaced as a security exception in your console. This happens due to same-origin policy.
Way, way way too late of an answer, but I had the same issue and the code below works in all browsers:
$('#myiframe').on('load', function () {
$(this).contents().on('click', function () {
alert('Click detected!');
})
})
It attaches onclick handler but only after iframe has been loaded. I am leaving this here for posterity and for anybody else looking for an answer to the same question.
In case you want to capture some data as well inside the iframe, this will work for you:
There is an iframe element with multiple images in it. The iframe is rendered inside of parent page. Whichever image you click inside the iframe, that image's id is sent back to the parent.
Inside iframe:
<script>
function vote(e) {
myMessage = e;
window.parent.postMessage(myMessage, "*");
return false;
}
</script>
<body><div>
<img id="Image1" src="file:///Users/abcd/Desktop/1.jpeg" width="200px" onclick="vote(this.id)">
</div></body>
Inside parent page:
</script>
function displayMessage (evt) {
var message = "You voted " + evt.data;
document.getElementById("received-message").innerHTML = message;
}
if (window.addEventListener) {
// For standards-compliant web browsers
window.addEventListener("message", displayMessage, false);
}
else {
window.attachEvent("onmessage", displayMessage);
}
</script>
<body><div id="received-message"></div></body>
This will not only capture the click but also capture the id of the element being clicked inside the iframe. Also, this does not require JQuery.
why are you using find to bind an event listener to an element that might not be there? Why not just try:
$('#mainWindow').ready(function()
{
$('#clickThis').on('click',function()
{
alert($(this).html());//or something
});
});
BTW: since your code is inside the ready callback of #mainWindow, there is no need to use $('#mainWindow') a second time, as this will scan the DOM tree a second time. Just use this or $(this), as it will reference the mainWindow element anyway.
If on doesn't work for you, don't forget to check if you have the latest version of jQuery included, too. That, too can be the reason why on isn't working.

How do I add a loading indicator to my page while my iframe loads?

I am currently creating a page where upon clicking a link an iframe is inserted into a div and it's contents loaded. I do this using the following jQuery call:
$('#mydiv').html('<iframe src="sourcelink.html" frameborder="0" width="760" height="2400" scrolling="no"></iframe>');
Sometimes the source content loads very slowly and, as a result, it looks like nothing is happening. I would like to have a simple loading animation while the content is loading while the iframe's content loads. When the iframe finishes loading it's content should pop in and the loading animation should go away.
I've been considering a couple ways I could do this (e.g. having a separate loader div to simply swap the two in and out) but I'm not sure of what the 'best' approach to solving this problem is. Perhaps I shouldn't be using .html()? I'm open to suggestion if there is a more correct solution.
Is there any reason you can't listen to the onload event of the iframe itself? It should fire after the child content has loaded.
Something like this:
showLoader();
$('#mydiv').html('<iframe src="sourcelink.html" frameborder="0" width="760" height="2400" scrolling="no"></iframe>');
$('#mydiv iframe').load(function() { hideLoader(); }
So In my case doing the following did for me..
The HTML
<iframe id="ifrmReportViewer" src="" frameborder="0" style="overflow:hidden;width:100%; height: 1000px;"></iframe>
and I was loading the iFrame on button of a click, so here is the JS
$(document).ready(function () {
$('body').on('click','#btnLoadiFrame',function () {
ShowLoader();
$('#ifrmReportViewer').attr('src', url);
$('#ifrmReportViewer').load(function () {
HideLoader();
});
});
});
You need to define a method that allows your iframe to highlight that it has finished loading, e.g.:
Main page:
var ChildFrameComplete = function()
{
$("#progress").hide();
};
var LoadChildFrame = function()
{
$("#progress").show();
$("#mydiv").html("<iframe src=\"sourcelink.html\" ... ></iframe>");
};
sourcelink.html:
$(function()
{
parent.ChildFrameComplete();
});
If the iframe is being sourced from the same domain as the parent page domain, it can call methods defined in the parent page through the window.parent property.
Just give the containing element (this case #myDiv) a background of a throbber and the iframe contents will overlap this when it's done loading.
That's the simplest.

Categories