MathJax not working with iFrame - javascript

I am trying to call MathJax Function on iFrame by click event. Here is the code
html
<body onLoad="ifon();">
<iframe name="richTextField" id="richTextField" style="border:#000000 1px solid; width:700px; height:300px;"></iframe>
<button onclick="refresh();"></button>
</body>
javascript
function ifon(){
richTextField.document.designMode = 'On';
}
function refresh(){
var richTextField = document.getElementById("richTextField");
if(richTextField != null) {
var get_iframe_text = richTextField.contentWindow.document.body.innerHTML;
if(get_iframe_text.slice(-6) == "$$<br>"){
//Trying to call MathJax on iFrame
MathJax.Hub.Queue(["Typeset",MathJax.Hub,richTextField]);
alert("Success");
}
}
}
The refresh() nested if condition will executed only if the last six character are $$<br>
Can any one help me how to call MathJax.Hub.Queue([]) on iFrame ?

You can not use MathJax from outside the iframe to process math within the iframe. You need to load MathJax inside the iframe itself. You can still trigger MathJax from outside if you need to by calling the MathJax that is inside the iframe, provided that the contents is from the same domain as the container. Otherwise, you would need to set up an event listener and use postMessage to communicate with the iframe.

At last I found a solution for this problem. Just replacing iFrame with HTML5 ContentEditale Div.
Now it is working Fine...

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();
}
});

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.

call javascript function from outside an iframe

I have one entire html openning inside an iframe that contains a javascript function getData().Now I am not sure how to call getData() from outside that frame.Also is it possible to call it from an external javascript file ?
You can get a reference to the frame window object from the window.frames property. See https://developer.mozilla.org/en/DOM/window.frames
UPDATE:
You can access the global context of a named iframe with window[framename]. e.g:
<iframe src="data.html" name="data"></iframe>
<script>
var myData = window.data.getData();
</script>
Although you will need to make sure the iframe has loaded.
In jQuery you can use the contents method if you want access to the iframe DOM:
$("iframe").contents()
All this is assuming the frame hosted within the same domain.
UPDATE[2]:
You asked if it is possible to call the getData function from an external js file. The answer is yes (if I understand you correctly). Here is an example:
<html>
<head>
<meta charset="utf-8">
<title>parent page</title>
</head>
<body>
<iframe src="data.html" name="data"></iframe>
<script src="getdata.js"></script>
</body>
</html>
Then in the getdata.js file you have:
var dataFrame = window.data;
// when the frame has loaded then call getData()
dataFrame.onload = function () {
var myData = dataFrame.getData();
// do something with myData..
}
Hope this answers your question :)
In certain situation there could be a neccessity of calling a javascript function inside an iframe from the parent document, and vice versa ie;
calling a javascript function in parent document from the iframe.
For example; the parent document have an iframe with id attribute ‘iFrameId‘, and the function ‘functionInIframe()‘ is defined in that iframe document.
Following code can call that iframe function from the parent document itself.
document.getElementById('iFrameId').contentWindow.functionInIframe();
And following code can call the function defined in parent document(functionInParent()) from the iframe itself.
parent.functionInParent();
This way javascript can interact between parent document and iframe.
This is the original post.
in these cases you name your iframe and the main body that uses/launches frame and then use parent.objectname, in JS everything is Object and you should be able to call getData()
a quick googling led me to this -> http://www.esqsoft.com/javascript_examples/iframe_talks_to_parent/

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.

Checking if iframe is ready to be written to

A 3rd party script on my web page creates an iframe. I need to know when this iframe is ready, so I can manipulate its DOM.
I can think of a hacky approach: repeatedly try to modify the iFrame's DOM, and return success when a change we make sticks between two attempts. For this to work, I would prefer a property I can check on the iframe repeatedly.
Is there an alternative, cross-browser evented approach to knowing that the iframe is ready? E.g. can we redefine the onLoad function to call into our code (but I don't know if I can do this, since I didn't create the iframe).
using jquery?
function callIframe(url, callback) {
$(document.body).append('<IFRAME id="myId" ...>');
$('iframe#myId').attr('src', url);
$('iframe#myId').load(function()
{
callback(this);
});
}
Question answered in jQuery .ready in a dynamically inserted iframe
Have a variable in the parent:
var setToLoad = false;
Follow it up with a function to set it:
function SetToLoad() {
setToLoad = true;
}
Then in the child iframe call this function using the window.opener
function CallSetToLoad() {
window.opener.SetToLoad();
}
window.onload = CallSetToLoad;
This won't run until the iframe is finished loading, and if it's in the same domain it'll allow access to the opener. This would require editing a small portion of the 3rd party script.
EDIT: Alternative solution
Given that you can't edit the script, you might try something like:
frames["myiframe"].onload = function()
{
// do your stuff here
}
Can you inject arbitrary scripting code into your iframe? If so, you should be able to make it so that some code executes in the iframe upon the the iframe loading that calls code in the parent page.
First: You probably won't be able to manipulate its dom when it loads html from other domain
And You probably are interested in DOMready.
Look here:
jQuery .ready in a dynamically inserted iframe
Bilal,
There's a document.readyState property that you can check (works in IE).
foo(){
if([your iframe id].document.readyState != "complete")
{
setTimeout("foo()", 500); //wait 500 ms then call foo
}
else
{
//iframe doc is ready
}
}
Arkady

Categories