Height Listener, jQuery - javascript

I'm creating a rich text editor.
Basically I have an iframe with design mode enabled. I'd like it to automatically resize when the user get near the bottom of the iframe while typing, or pasting text.
I have the function to change size.
function changeHeight() {
$(iframe).height($(iframe.contentWindow.document).height());
}
I just need to add a listener. I can't for the life of me find one that works!
Any ideas?
Much appreciated
-Will

Do this: http://sonspring.com/journal/jquery-iframe-sizing and add an onkeypress listener to check for resize.
Fair warning: if the content is not within the same domain --- it will NOT work due to XSS vulnerability prevention (you cannot trap the keypress event in this case).
This has been tested in IE7 to work, should work across most browsers. You're not actually attaching to the iFrame itself either, so much as the element you're interested in (which could very well be the body).
<script type="text/javascript" language="javascript">
$(document).ready(function() {
$('#IFRAME').contents().find('textarea').bind('keypress', function() {
//Dostuff
})
});
</script>
<iframe src="/whatever.html" width="800" height="400" id="IFRAME" ></iframe>
Where you have a textarea (or div, or whatever) inside the iframe ... change the filter to your heart's content. Iframe resize code shows up in the sonspring article.
**
Edit again for code that attaches to IFRAME directly
Source [only replaced jQuery functions for native DOM. I'll clean out what I can when I have more time]:
http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_25589672.html
**
<script>
$(document).ready(function() {
var f = $('#IFRAME')[0];
var fwin = f.contentWindow || f.contentDocument;
fwin.document.designMode = 'on';
var evt_key = function(e) {
e = e || fwin.event;
var range = null, ret = null;
if (fwin.document.selection) {
range = fwin.document.selection.createRange();
ret = range.parentElement();
}
else if (fwin.window.getSelection) {
var range = fwin.window.getSelection().getRangeAt(0);
ret = range.commonAncestorContainer.parentNode || fwin.document;
}
fwin.parent.eventCallback();
};
if (fwin.document.attachEvent) {
fwin.document.attachEvent('onkeypress', evt_key);
}
else if (fwin.document.addEventListener) {
fwin.document.addEventListener('keypress', evt_key, false);
}
})
function eventCallback() {
alert('Key Pressed');
}
</script>
<iframe src="#" width="800" height="400" id="IFRAME" ></iframe>

Related

Get parent of clicked tag inside of iframe

I've an iframe that contain an HTML page.Now I want to get class of the parent item that clicked.
this is my ifram:
<iframe src="//example.com" id="frame" ></iframe>
this is css:
#frame{ width:380px; height:420px;}
this is my script:
$(document).ready(function() {
var iframe = document.getElementById('frame');
var innerDoc = iframe.contentDocument || iframe.contentWindow.document.body;
$(innerDoc).on('click', function(e) {
var thisID = ((e.target).id);
alert(thisID);
alert(innerDoc.getElementById(thisID));
$(thisID).click(function() {
var Allclassnames = $(thisID).parent();
console.log(Allclassnames);
});
});
});
but it return the item was clicked only.how to fix it?
Demo:DEMO
NOTE:these are in a same domain.maybe below DEMO not worked for this reason.but I'm sure that my HTML is inside of the same domain with my web site.
thank you.
Add sandbox attributes to the iframe
<iframe src="/example.html" id="frame" sandbox="allow-scripts allow-same-origin"></iframe>
Change the script to
<script>
$('#frame').load(function() {
$('#frame').contents().on('click', function(e) {
var thisID = ((e.target).id);
alert(thisID);
alert($('#'+thisID,this));
$('#'+thisID,this).click(function() {
var Allclassnames = $(this).parent();
console.log(Allclassnames);
});
});
});
</script>
Make sure that every element in frame doc. have some id or else the alert() may throw an error.
To see the console message of iframe you need to change the scope from the scope dropdown , it's in console tab besides the filter icon in the chrome developer tools.
You cannot interact with the contents of an iframe unless it is on the same domain as the parent document.
See:
https://en.wikipedia.org/wiki/Same-origin_policy

Is it safe to use '*' as the origin of a message from inside an iframe?

The problem was, that I had an <iframe> with dynamically changing content. I couldn't find any other way to dynamically change the height of the <iframe> element than sending new height each time when it changes to the bloggers website by parent.postMessage. The solution works (maybe it can help others, but the thing is that I'm not sure if I have done it in a safe way.
I just want to ask if it's safe to use window.parent.postMessage('Some message', '*') in that way?
Embeded site:
<script type="text/javascript">
var framesHeight = 0;
setInterval(function(){
var newFramesHeight = window.document.getElementsByTagName('html')[0].offsetHeight;
if (newFramesHeight !== framesHeight) {
window.parent.postMessage(newFramesHeight, '*');
framesHeight = newFramesHeight;
}
}, 500);
</script>
As you can see, each time when the hight changes I send a new message.
On the bloggers website I want to embed this:
<script>
window.addEventListener('message', function (evt) {
if (evt.origin === 'http://mypage.com' && !isNaN(evt.data)) {
document.getElementById('embedID').style.height = evt.data+'px';
}
}, false);
</script>
<iframe id="embedID" src="http://mypage.com/embed/11" frameborder="0" style="width: 100%; height: 100%;" scrolling="no"></iframe>

Saving some contenteditables localstorage - - -

I'm trying to save more than one entry of contenteditable content into my localstorage for a Chrome extension. My current code saves just one contenteditable section fine, but when I try to add another Id of a seperate contenteditable section it either deletes all the saved information or doesn't do anything at all. I'm pretty novice in JS, so I hope I'm just making a simple mistake. My html looks like this:
<div id = "content">
<div id= "tcontent" contenteditable="true" data-ph=" Make a note . . . "
style= "height: 300px; overflow: auto"></div>
<div id = "content2">
<div id= "tcontent2" contenteditable="true" data-ph= " Make a note . . . "
style= "height: 300px; overflow: auto"></div>
</div>
And this is my Javascript:
window.addEventListener('load', onLoad); function onLoad() {
checkEdits();
}
function checkEdits() {
if(localStorage.userEdits!=null) {
document.getElementById("tcontent", "tcontent2").innerHTML += localStorage.userEdits;
}
};
document.onkeyup = function (e) {
e = e || window.event;
console.log(e.keyCode);
saveEdits();
};
function saveEdits() {
var editElem = document.getElementById("tcontent", "tcontent2");
var userVersion = editElem.innerHTML;
localStorage.userEdits = userVersion;
};
Basically this code will only save one (the content I place first into the getElementbyId). Isn't there a way to save both of the 'content's?
I've been playing around with all my little knowledge of javascript I have but can't seem to see what I'm doing wrong or what I should be doing here.
Much thanks for any and all help.
document.getElementById is a method that only takes one element's id. You are currently trying to pass two strings to the method. That will not work.
Please refer to the documentation here: https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
Also, you must assign the innerHTML of each element individually to each piece of saved content in localStorage.
Granted that you are fairly new to the Language I do not want to overcomplicate the answer for you. With that said, please find below your code with a few modifications to be able to save both pieces in localStorage respectively:
window.addEventListener('load', onLoad); function onLoad() {
checkEdits();
}
function checkEdits() {
if(localStorage.userEdits1!=null) {
document.getElementById("tcontent").innerHTML = localStorage.userEdits1;
}
if(localStorage.userEdits2!=null) {
document.getElementById("tcontent2").innerHTML = localStorage.userEdits2;
}
};
document.onkeyup = function (e) {
e = e || window.event;
console.log(e.keyCode);
saveEdits();
};
function saveEdits() {
var editElem1 = document.getElementById("tcontent");
var editElem2 = document.getElementById("tcontent2");
localStorage.userEdits1 = editElem1.innerHTML;
localStorage.userEdits2 = editElem2.innerHTML;
};

Get A tag href from nested iframe [duplicate]

I would like to manipulate the HTML inside an iframe using jQuery.
I thought I'd be able to do this by setting the context of the jQuery function to be the document of the iframe, something like:
$(function(){ //document ready
$('some selector', frames['nameOfMyIframe'].document).doStuff()
});
However this doesn't seem to work. A bit of inspection shows me that the variables in frames['nameOfMyIframe'] are undefined unless I wait a while for the iframe to load. However, when the iframe loads the variables are not accessible (I get permission denied-type errors).
Does anyone know of a work-around to this?
If the <iframe> is from the same domain, the elements are easily accessible as
$("#iFrame").contents().find("#someDiv").removeClass("hidden");
Reference
I think what you are doing is subject to the same origin policy. This should be the reason why you are getting permission denied type errors.
You could use .contents() method of jQuery.
The .contents() method can also be used to get the content document of an iframe, if the iframe is on the same domain as the main page.
$(document).ready(function(){
$('#frameID').load(function(){
$('#frameID').contents().find('body').html('Hey, i`ve changed content of <body>! Yay!!!');
});
});
If the iframe src is from another domain you can still do it. You need to read the external page into PHP and echo it from your domain. Like this:
iframe_page.php
<?php
$URL = "http://external.com";
$domain = file_get_contents($URL);
echo $domain;
?>
Then something like this:
display_page.html
<html>
<head>
<title>Test</title>
</head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
cleanit = setInterval ( "cleaning()", 500 );
});
function cleaning(){
if($('#frametest').contents().find('.selector').html() == "somthing"){
clearInterval(cleanit);
$('#selector').contents().find('.Link').html('ideate tech');
}
}
</script>
<body>
<iframe name="frametest" id="frametest" src="http://yourdomain.com/iframe_page.php" ></iframe>
</body>
</html>
The above is an example of how to edit an external page through an iframe without the access denied etc...
Use
iframe.contentWindow.document
instead of
iframe.contentDocument
I find this way cleaner:
var $iframe = $("#iframeID").contents();
$iframe.find('selector');
You need to attach an event to an iframe's onload handler, and execute the js in there, so that you make sure the iframe has finished loading before accessing it.
$().ready(function () {
$("#iframeID").ready(function () { //The function below executes once the iframe has finished loading
$('some selector', frames['nameOfMyIframe'].document).doStuff();
});
};
The above will solve the 'not-yet-loaded' problem, but as regards the permissions, if you are loading a page in the iframe that is from a different domain, you won't be able to access it due to security restrictions.
You can use window.postMessage to call a function between page and his iframe (cross domain or not).
Documentation
page.html
<!DOCTYPE html>
<html>
<head>
<title>Page with an iframe</title>
<meta charset="UTF-8" />
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
var Page = {
id:'page',
variable:'This is the page.'
};
$(window).on('message', function(e) {
var event = e.originalEvent;
if(window.console) {
console.log(event);
}
alert(event.origin + '\n' + event.data);
});
function iframeReady(iframe) {
if(iframe.contentWindow.postMessage) {
iframe.contentWindow.postMessage('Hello ' + Page.id, '*');
}
}
</script>
</head>
<body>
<h1>Page with an iframe</h1>
<iframe src="iframe.html" onload="iframeReady(this);"></iframe>
</body>
</html>
iframe.html
<!DOCTYPE html>
<html>
<head>
<title>iframe</title>
<meta charset="UTF-8" />
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
var Page = {
id:'iframe',
variable:'The iframe.'
};
$(window).on('message', function(e) {
var event = e.originalEvent;
if(window.console) {
console.log(event);
}
alert(event.origin + '\n' + event.data);
});
$(window).on('load', function() {
if(window.parent.postMessage) {
window.parent.postMessage('Hello ' + Page.id, '*');
}
});
</script>
</head>
<body>
<h1>iframe</h1>
<p>It's the iframe.</p>
</body>
</html>
I prefer to use other variant for accessing.
From parent you can have a access to variable in child iframe.
$ is a variable too and you can receive access to its just call
window.iframe_id.$
For example, window.view.$('div').hide() - hide all divs in iframe with id 'view'
But, it doesn't work in FF. For better compatibility you should use
$('#iframe_id')[0].contentWindow.$
Have you tried the classic, waiting for the load to complete using jQuery's builtin ready function?
$(document).ready(function() {
$('some selector', frames['nameOfMyIframe'].document).doStuff()
} );
K
I create a sample code . Now you can easily understand from different domain you can't access
content of iframe .. Same domain we can access iframe content
I share you my code , Please run this code
check the console . I print image src at console. There are four iframe , two iframe coming from same domain & other two from other domain(third party) .You can see two image src( https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif
and
https://www.google.com/logos/doodles/2015/arbor-day-2015-brazil-5154560611975168-hp2x.gif
)
at console and also can see two permission error(
2
Error: Permission denied to access property 'document'
...irstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument...
) which is coming from third party iframe.
<body id="page-top" data-spy="scroll" data-target=".navbar-fixed-top">
<p>iframe from same domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
src="iframe.html" name="imgbox" class="iView">
</iframe>
<p>iframe from same domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
src="iframe2.html" name="imgbox" class="iView1">
</iframe>
<p>iframe from different domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
src="https://www.google.com/logos/doodles/2015/googles-new-logo-5078286822539264.3-hp2x.gif" name="imgbox" class="iView2">
</iframe>
<p>iframe from different domain</p>
<iframe frameborder="0" scrolling="no" width="500" height="500"
src="http://d1rmo5dfr7fx8e.cloudfront.net/" name="imgbox" class="iView3">
</iframe>
<script type='text/javascript'>
$(document).ready(function(){
setTimeout(function(){
var src = $('.iView').contents().find(".shrinkToFit").attr('src');
console.log(src);
}, 2000);
setTimeout(function(){
var src = $('.iView1').contents().find(".shrinkToFit").attr('src');
console.log(src);
}, 3000);
setTimeout(function(){
var src = $('.iView2').contents().find(".shrinkToFit").attr('src');
console.log(src);
}, 3000);
setTimeout(function(){
var src = $('.iView3').contents().find("img").attr('src');
console.log(src);
}, 3000);
})
</script>
</body>
If the code below doesn't work
$("#iFrame").contents().find("#someDiv").removeClass("hidden");
Here is the reliable way to make it work:
$(document).ready(function(){
setTimeout(
function () {
$("#iFrame").contents().find("#someDiv").removeClass("hidden");
},
300
);
});
This way the script will run after 300 miliseconds, so it'll get enough time for iFrame to be loaded and then the code will come into action. At times the iFrame doesn't load and script tries to execute before it. 300ms can be tweaked to anything else as per your needs.
For even more robustness:
function getIframeWindow(iframe_object) {
var doc;
if (iframe_object.contentWindow) {
return iframe_object.contentWindow;
}
if (iframe_object.window) {
return iframe_object.window;
}
if (!doc && iframe_object.contentDocument) {
doc = iframe_object.contentDocument;
}
if (!doc && iframe_object.document) {
doc = iframe_object.document;
}
if (doc && doc.defaultView) {
return doc.defaultView;
}
if (doc && doc.parentWindow) {
return doc.parentWindow;
}
return undefined;
}
and
...
var frame_win = getIframeWindow( frames['nameOfMyIframe'] );
if (frame_win) {
$(frame_win.contentDocument || frame_win.document).find('some selector').doStuff();
...
}
...
I ended up here looking for getting the content of an iframe without jquery, so for anyone else looking for that, it is just this:
document.querySelector('iframe[name=iframename]').contentDocument
This solution works same as iFrame. I have created a PHP script that can get all the contents from the other website, and most important part is you can easily apply your custom jQuery to that external content. Please refer to the following script that can get all the contents from the other website and then you can apply your cusom jQuery/JS as well. This content can be used anywhere, inside any element or any page.
<div id='myframe'>
<?php
/*
Use below function to display final HTML inside this div
*/
//Display Frame
echo displayFrame();
?>
</div>
<?php
/*
Function to display frame from another domain
*/
function displayFrame()
{
$webUrl = 'http://[external-web-domain.com]/';
//Get HTML from the URL
$content = file_get_contents($webUrl);
//Add custom JS to returned HTML content
$customJS = "
<script>
/* Here I am writing a sample jQuery to hide the navigation menu
You can write your own jQuery for this content
*/
//Hide Navigation bar
jQuery(\".navbar.navbar-default\").hide();
</script>";
//Append Custom JS with HTML
$html = $content . $customJS;
//Return customized HTML
return $html;
}

Adding image using javascript

I have a html page in which there is an image in anchor tag code is :
<img src="images/test.png" />
on body onload event i am calling a javascript function which dynamically changes the image . My code is:
<script type="text/javascript">
function changeImage()
{
document.getElementById('x').innerHTML= '<img src="images/test2.png" />';
}
</script>
This is working fine in firefox but not working in google chrome and ie. Please help..
try this:
<img id="y" src="images/test.png" />
in js
function changingImg(){
document.getElementById("y").src="./images/test2.png"
}
Tested in Chrome and IE.
Then try this: [hoping that id of <a> is available and have at least one img tag]
var x = document.getElementById("x");
var imgs = x.getElementsByTagName("img");
imgs[0].src="./images/img02.jpg";
try following instead of changing innerHTML.
function changeImage()
{
var parent = documeent.getElementById('x');
parent.getElementsByTagName("img")[0].src = "newUrl";
}
As others have indicated, there are many ways to do this. The A element isn't an anchor, it's a link. And no one really uses XHTML on the web so get rid of the XML-style syntax.
If you don't have an id for the image, then consider:
function changeImage(id, src) {
var image;
var el = document.getElementById(id);
if (el) {
image = el.getElementsByTagName('img')[0];
if (image) {
image.src = src;
}
}
}
Then you can use an onload listener:
<body onload="changeImage('x', 'images/test.png');" ...>
or add a script element after the link (say just before the closing body tag) or use some other strategy for running the function after the image is in the document.

Categories