How to get id of element in an iframe? - javascript

I have an <iframe> with a local file embedded. I don't know how to get a specific element in this document.
I have tried window.top.document.getElementById('numPages') and $("#myiframe").contents().find("#numPages") to get element with an id of numPages.

Try using .contentDocument
eg:
var iframe = document.getElementById("myFrame"),
idocument = iframe.contentDocument
// Use idocument instead of document

To get the element in plain javascript try using contentWindow
document.getElementById('myiframe').contentWindow.document.body.getElementById('numPages');

By this way, You can get frame id and set css property inside frame element. It'll work 100%.
<script>
window.onload = function WindowLoad(event) {
let iframe = document.getElementsByTagName("iframe")[0];
var iframevar = document.getElementById(iframe.id);
var elmnt = iframevar.contentWindow.document.getElementById("header_27");
elmnt.style.color = 'black';
var elmnt = iframevar.contentWindow.document.getElementById("header_59");
elmnt.style.color = 'black';
}
</script>

Related

HTML JavaScript delay downloading img src until node in DOM

Hi I have markup sent to me from a server and I set it as the innerHTML of a div element for the purpose of traversing the tree, finding image nodes, and changing their src values. Is there a way to prevent the original src value from being downloaded?
Here is what I am doing
function replaceImageSrcsInMarkup(markup) {
var div = document.createElement('div');
div.innerHTML = markup;
var images = div.getElementsByTagName('img');
images.forEach(replaceSrc);
return div.innerHTML;
}
The problem is that in browsers as soon as you do:
var img = document.createElement('img'); img.src = 'someurl.com' the browser fires off a request to someurl.com. Is there a way to prevent this without resorting to parsing the markup myself? If there is in no other way does anyone know a good way of parsing the markup with as little code as possible to accomplish my goal?
I know you are already happy with your solution, but I think it would be worth sharing a safe method for future users.
You can now simply use the DOMParser object to generate an external document from your HTML string, instead of using a div created by your current document as container.
DOMParser specifically avoids the pitfalls mentioned in the question and other threats: no img src download, no JavaScript execution, even in elements attributes.
So in your case you can safely do:
function replaceImageSrcsInMarkup(markup) {
var parser = new DOMParser(),
doc = parser.parseFromString(markup, "text/html");
// Manipulate `doc` as a regular document
var images = doc.getElementsByTagName('img');
for (var i = 0; i < images.length; i += 1) {
replaceSrc(images[i]);
}
return doc.body.innerHTML;
}
Demo: http://jsfiddle.net/94b7gyg9/1/
Note: with your current code, browsers will still try downloading the resource initially specified in your img nodes src attribute, even if you change it before the end of JS execution. Trace network transactions in this demo: http://jsfiddle.net/94b7gyg9/
Rather than append the new markup to the DOM before you change the img sources, create an element, set it's inner HTML, change the source of the images and then finally, append the changed markup to the page.
Here's a fully-worked sample.
<!DOCTYPE html>
<html>
<head>
<script>
"use strict";
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}
//function allByClass(className,parent){return (parent == undefined ? document : parent).getElementsByClassName(className);}
function allByTag(tagName,parent){return (parent == undefined ? document : parent).getElementsByTagName(tagName);}
function newEl(tag){return document.createElement(tag);}
//function newTxt(txt){return document.createTextNode(txt);}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded()
{
byId('goBtn').addEventListener('click', onGoBtnClick, false);
}
var dummyString = "<img src='img/girl.png'/><img src='img/gfx07.jpg'/>";
function onGoBtnClick(evt)
{
var div = newEl('div');
div.innerHTML = dummyString;
var mImgs = allByTag('img', div);
for (var i=0, n=mImgs.length; i<n; i++)
{
mImgs[i].src = "img/murderface.jpg";
}
document.body.appendChild(div);
}
</script>
<style>
</style>
</head>
<body>
<button id='goBtn'>GO!</button>
</body>
</html>
You could directly parse the markup string using a regex to replace the img src. Searching for all the img src urls in the string and then replacing them with the new url.
var regex = /<img[^>]+src="?([^"\s]+)"?\s*\/>/g;
var imgUrls = [];
while ( m = regex.exec( markup ) ) {
imgUrls.push( m[1] );
}
imgUrls.forEach(function(url) {
markup = markup.replace(url,'new-url');
});
Another solution might be, if you have access to it, to set the all the img src to an empty string, and put the url in in a data-src attribute. Having your markup string look like something like this
markup = '
';
Then setting this markup to your div.innerHTML won't trigger any download from the browser. And you can still parse it using regular DOM selector.
div.innerHTML = markup;
var images = div.getElementsByTagName('img');
images.forEach(function(img){
var oldSrc = img.getAttribute('data-src');
img.setAttribute('src', 'new-url');
});

Don't load scripts appended with innerHTML?

I'm appending a whole HTML page to a div (to scrape). How do I stop it from requesting script, and css files ? I tried immediately removing those nodes but they still get requested.
It's for a browser addon, I'm scraping with JS
As #adeneo wrote you don't have to add the html to a page in order to scrape information from it, you can turn it into DOM tree that is disconnected from the page DOM and process it there.
In jQuery it is simple $("html text here"). Then you can scrape it using the API,
eg.
function scrape_html(html_string) {
var $dom = $(html_string);
var name = $dom.find('.name').text();
return name;
}
without jQuery:
function scrape_html(html_string) {
var container = document.createElement('div');
container.innerHTML = html_string;
var name = container.getElementsByClassName('name')[0].innerText;
return name;
}
Setting the innerHTML of a temporary HTML element that has not been added to the document, will not execute scripts, and since it does not belong to your document, the style will not be applied either.
This will give you an opportunity to strip out any unwanted elements before copying the innerHTML to your own document.
Example:
var temp = document.createElement('div');
temp.innerHTML = html; // the HTML of the 'other' page.
function removeElements(element, tagName)
{
var elements = temp.getElementsByTagName(tagName);
while(elements.length > 0)
{
elements[0].parentNode.removeChild(elements[0]);
}
}
removeElements(temp, 'script');
removeElements(temp, 'style');
removeElements(temp, 'link');
container.innerHTML = temp.innerHTML;

get all content of div including content of iframes using javascripts not jquery

I Have a div something like this
<div id="tid">
<iframe>
<html>
<body>
<scripts></scripts>
<iframe>...
//more content
<ifram>
</body>
</html>
</iframe>
</div>
I want to get below using javascript.
<iframe>
<html>
<body>
<scripts></scripts>
<iframe>...
//more content and cannot guess how many iframes are there.
<ifram>
</body>
</html>
</iframe>
InnerHtml only return first iframe only. I tried with .contentDocument.getElementsByTagName('body')[0].innerHTML. but this only return first iframe. I want get all the content into string variable without using jquery.
Thanks
YOU NEED TO REPLACE < WITH < AND > WITH > TO PRINT HTML TAGS AS A PLAIN TEXT.
try this code,
var content = document.getElementById('tid').innerHTML;
content = content.replace(/</g,"<").replace(/>/g,">");
document.getElementById('content').innerHTML = content;
SEE THIS DEMO
if you want to reuse that div html, simply add that content to any other html element like below,
var content = document.getElementById('tid').innerHTML;
//the variable content contains the html inside "tid" div.
var iDiv = document.createElement('div');
iDiv.id = 'newDiv';
iDiv.innerHTML = content;
document.getElementsByTagName('body')[0].appendChild(iDiv);
SEE THIS DEMO
If you only want the body tags this should work.
var els = document.getElementsByTagName("body");
var allContent = "";
for (var i=0; i < els.length; i++) {
allContent += els[i].innerHTML;
}
Do this
var iframe = document.getElementById('iframeID');
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
now you can use iframeDocument to access content of iframe, jquery does the same
UPDATE
You can do something like this ..
var myDiv = document.getElementById("tid");
var iframes = myDiv.getElementsByTagName("iframe");
// now loop over the iframes
for(iframe in iframes){
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
var internalIframes = iframeDocument.getElementsByTagName("iframe");
if(internalIframes.length > 1){
// start the for in loop again
}
}
can not do this because of same origin policy

How to get innerHTML content of iframe element

hi i am trying to get inner HTML of iframe element
my html document a structure is like this
<body>
<div>
<iframe id="frame1">
<html>
<button id="mybutton">click me</button>
</html>
</iframe>
</div>
</body>
i am creating a chrome extension i have to show an alert when button with id mybutton is clicked i write an a content script
var greeting = "hola, ";
document.body.innerHTML='<div><iframe id="frame1" src="http://onemoredemo.appspot.com/"></iframe></div>' ;
var iframe = document.getElementById("frame1");
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document
var button = iframeDocument.getElementById("mybutton") ;
if(button ==null)
alert("button is null") ;
i installed this extension in chrome when i visit a page then document body is changed into an iframe with a button in it.
but i am facing an alert which has button is null but there is button in iframe why i am getting null for this button??
To get the button inside of the iframe, this could work:
var iframe = document.getElementById("frame1");
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
var button = iframeDocument.getElementById("mybutton");
Obviously, you can navigate to get what you want with iframeDocument, and use .innerHTML as you seem to know. You cannot get the contents of the iframe if the iframe is pointing to a domain other than its parent.
UPDATE:
You need to use the code to get the frame's document and its contents after it's ready, so you should use something like this:
window.onload = function () {
var greeting = "hola, ";
var div1 = document.createElement("div");
var frame1 = document.createElement("iframe");
frame1.id = "frame1";
frame1.onload = function () {
alert("loaded");
var iframe = document.getElementById("frame1");
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
var button = iframeDocument.getElementById("mybutton");
if (button == null) {
alert("button is null");
}
};
frame1.src = "http://onemoredemo.appspot.com";
div1.appendChild(frame1);
document.body.appendChild(div1);
};
DEMO: http://jsfiddle.net/nqTnz/
The important thing is how the elements are created and appended to the DOM - not just using innerHTML. The onload method of the iframe is to guarantee it's ready. The actual manipulation code won't work in the jsFiddle because the cross-domain problems, but is what you should need.
In jQuery's source code the solution to get the iframe document is like this:
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
And then you can usually use getElementsByTagName or getElementById to select the DOM-Elements:
var elem;
if (iframeDocument) {
elem = iframeDocument.getElementById('mybutton');
}
Have You tried ????
iframe.srcdoc="<HTML><a id='some_id'>old</a><script>function run(src){eval(src);}</script></HTML>";
And then
iframe.contentWindow.run("document.getElementById('some_id').innerHTML='new content';");

Need javascript code to run multiple times in one page. For each div

I forgot to include 'run multiple times in one page' on my last question located here: Create iframe with javascript appending to a div
I need to run the code on multiple div's within the same page. Right now the code below only runs once on the last div. For example if I have 3 div's, all 3 should have an iframe appended to it. Regular javascript. Trying not to use JQuery.
window.onload = function(){
var link = "http://www.somesite.com"
var iframe = document.createElement('iframe');
iframe.frameBorder=0;
iframe.width="300px";
iframe.height="250px";
iframe.id="randomid";
iframe.setAttribute("src", link);
document.getElementById("ad54").appendChild(iframe); //<--this id will be dynamically generated to match div's
}
<div class="ad" id="1"></div>
<div class="ad" id="2"></div>
<div class="ad" id="3"></div>
EDIT: Tested in IE9, Chrome, Safari, Firefox and opera. This code works. No JQuery or loops needed. This code will create the iframe wherever you use it.
var link = "http://www.somesite.com"
document.write(iframe);
var myIframe = parent.document.getElementById("randomid");
myIframe.height = 250;
myIframe.width = 300;
myIframe.src = link;
myIframe.style.border = "0px";
myIframe.style.padding = "0px";
window.onload = function() {
var elements = document.getElementsByTagName('div');
for (var i = 0; i < elements.length; i++) {
append_iframe( elements[i] );
}
}
function append_iframe( div ) {
var link = "http://www.somesite.com"
var iframe = document.createElement('iframe');
iframe.frameBorder=0;
iframe.width="300px";
iframe.height="250px";
iframe.id="randomid";
iframe.setAttribute("src", link);
div.appendChild(iframe);
}
Not a jQuery guy but I think this works
$("div").each(function(d) {
var link = "http://www.somesite.com"
var iframe = document.createElement('iframe');
iframe.frameBorder=0;
iframe.width="300px";
iframe.height="250px";
iframe.id="randomid";
iframe.setAttribute("src", link);
this.appendChild(iframe);
});

Categories

Resources