I am developing a website updater. My idea is to have certain HTML elements be part of the class updatable. I will then change each element with that class to a textarea element. That way it can be updated.
I am dividing the updater.html page into 2 areas; the left side a select element but the right side shows some HTML from the webpage I am updating. I want all the html on the right side to be affected by a specific css style sheet(the style sheet of the webpage I am updating). How can I do that?
Because the style sheet is external, I dont want to open the style sheet, read it into memory(is this possible in javascript) then insert it into the iframe that contains the updatable HTML.
<html>
<head>
</head>
<body>
<table>
<tr>
<td class="updaterSection">
<select>
<option> home </option>
...
</select>
</td>
<td class="updatableWebpage">
<!-- I want all the HTML in this div to be affected by the external css stlyle sheet -->
<iframe src="/css/specStyle.css">
<p> uneditable stuff </p>
<textarea> editable stuff </textarea>
</iframe>
</td>
</tr>
</table>
</body>
</html>
As far as i konw, this is not how you use an iframe,
The inside of the <iframe> will be replaced by the page put in the src.
The code you posted is just going to display the css page on your webpage. (a simple example using you code: http://jsfiddle.net/W5ggT/ )
So either you put all the html that is inside your iframe into a new html page which contains a link to the special stylesheet in its header.
Or you use some ajax to refresh that, but I'm not sure to fully understand what you want.
You can manipulate the DOM of the html webpage inside your iframe using javascript.
That is only possible if it is in the same domain.
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Iframe manipulation</title>
<script type='text/javascript'>
window.onload = function () {
var iframe = document.getElementById('iframe');
// cross browser solution for handling iframe
var contentProp = (iframe.contentWindow)?iframe.contentWindow.document:iframe.contentDocument;
var head = contentProp.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.rel = "stylesheet";
link.type = "text/css";
link.href = "/stylesheet/css.css"; // the new stylesheet to add to iframe
head.appendChild(link);// adds stylesheet to iframe
});
</script>
</head>
<body>
<iframe id='iframe' src='test2.html'></iframe>
</body>
</html>
add external.css your css file in the head section (within tag).
<html>
<head>
<link rel="stylesheet" type="text/css" href="path to the css file">
</head>
<body> </body>
</html>
give a different class name to the tag that you want to style. But the style in your external.css file.
Hope it helps.
Related
tldr: I'm looking to keep the other text in the srcdoc attribute of an iframe alone, but only swap out the link to the stylesheet using vanilla Javascript.
Longer version:
I'm customizing a Publii blog template and embedding a Cusdis comment widget using their hosted JS SDK.
Publii makes use of HTML, CSS, Javascript, and Handlebars.
The Cusdis widget works by pasting the following code in your html document:
<div id="cusdis_thread"
data-host="https://cusdis.com"
data-app-id="{{ APP_ID }}"
data-page-id="{{ PAGE_ID }}"
data-page-url="{{ PAGE_URL }}"
data-page-title="{{ PAGE_TITLE }}"
>
<script async src="https://cusdis.com/js/cusdis.es.js"></script>
Then, the Cusdis SDK will find the element with id cusdis_thread, then mount the iframe widget on it:
<iframe srcdoc='<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cusdis.com/js/style.css">
<base target="_parent" />
<link>
<script>
window.CUSDIS_LOCALE = undefined
window.__DATA__ = {"host":"https://cusdis.com","appId":"...","pageId":"...","pageUrl":"...","pageTitle":"..."}
</script>
</head>
<body>
<div id="root"></div>
<script src="https://cusdis.com/js/iframe.umd.js" type="module"
</script>
</body>
</html>'
style="width: 100%; border: 0px none; height: 323px;">
#document
</iframe>
My issue is the following:
I want to edit the Cusdis widget's CSS so that the look goes better with my site.
I've tried editing my own stylesheet and selecting Cusdis's CSS classes, but the changes aren't reflected in the output (even with !important). I suspect that it's because the widget generates an iframe, and the elements I want to edit are contained in the iframe.
The workaround seems to be to replace the stylesheet in the iframe's "srcdoc" attribute with a link to another external stylesheet
Because the iframe is automatically generated by Cusdis's SDK, I can't edit that HTML on my end. I'm trying to find a way to replace the stylesheet in the generated iframe's srcdoc using vanilla Javascript.
Here is what I've tried:
Using setAttribute to replace the contents of the attribute:
document.querySelector("#cusdis_thread iframe").setAttribute('srcdoc', '<!DOCTYPE html><html><head><link rel="stylesheet" href="..."><base target="_parent" /><link><script> window.CUSDIS_LOCALE = undefined window.__DATA__ = {"host":"https://cusdis.com", appId":"...","pageId":"{{id}}","pageUrl":"{{url}}","pageTitle":"{{title}}"} </script> </head> <body> <div id="root"></div> <script src="https://cusdis.com/js/iframe.umd.js" type="module"> </script></body></html>');
Result: It worked in theory, but the comment section wasn't generated. When I inspected the code, the attribute's content was replaced. However, I'm using handlebars expressions {{}} to add the PAGE_ID, PAGE_URL, and PAGE_TITLE dynamically, but these expressions are kept inside the srcdoc (so, instead of the iframe displaying the actual URL in the window.__DATA__ =... section, it's still showing the handlebars expression {{url}}).
So, I'm looking for a solution which will keep the other text in the srcdoc attribute alone, but only swap out the link to the stylesheet. Here are my attempts at this:
Using .replace to find the url of Cusdis's stylesheet and replacing it with my own:
document.querySelector("#cusdis_thread iframe").replace("https://cusdis.com/js/style.css", "...");
Result: it was ignored
Using setAttribute for just the stylesheet:
document.querySelector("#cusdis_thread iframe").setAttribute('srcdoc', '<link rel="stylesheet" href="...">');
Result: it was ignored
Since this iframe is loaded through its srcdoc attribute, you can access its inner document from your own document, (because about:srcdoc is magic).
So the best will be to wait for the iframe to load, and to inject your own <link> in there (or modify the StyleSheets as you wish).
const iframe = document.querySelector("iframe");
iframe.addEventListener("load", (evt) => {
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = "your-stylesheet.css";
iframe.contentDocument.head.append(link);
}, { once: true });
Live Demo (as a jsfiddle because StackSnippets null-origined iframes are dark-magic against same-origin...
The complicated part might be to detect when this iframe is inserted into the document. It seems you already are able to do so, but for the ones who can't, they could either check which event the library fires from, or in worst case scenario, use a MutationObserver.
I have two separate files one with my html code and with my javaScript. What I am trying to do is create a function in javascript then call that function in the html. Both files are in the same folder along with the image. I'm new to both languages and to this site so please go easy;
I would really appreciate it if someone could help me please.`
JavaScript to load image below:
var menu = new image();
menu.src = "Fitness App Entry Scrren.jpg"
function menuScreen(){
document.getElementById("menu").getAttribute("src");
}
Html code to call function:
<!DOCTYPE html>
<html>
<head>
<body src="Functions.js">
<script onload="menuScreen()"></script>
</body>
<head>
</html>
What you are doing is against the rules of HTML. First of all, <body></body> should be outside of <head></head>. You should have <script></script> in either <head></head> or <body></body>. The <body> tag should have the onload attribute set to menuScreen(), and the <script> tag's src attribute should be set to Functions.js (as John Hascall said). By the way, John Hascall is right, there is no element with the ID of "menu" so it won't work unless you create a <div> or <iframe> with the specific ID and append the image to it in your Functions.js file.
So, your JavaScript code should look like this:
var menu = new Image(); // note that the constructor is capitalized
menu.src = "Fitness App Entry Screen.jpg";
// Create a <div> with the image within it.
var division = document.createElement("div");
division.setAttribute("id", "menu");
division.appendChild(menu);
document.body.appendChild(division);
function menuScreen() {
division.getAttribute("src"); // you can use division because it has the id of menu
}
And here is your HTML code to run the page (according to the HTML5 specifications, note that):
<!DOCTYPE html>
<html>
<head>
<script src="Functions.js"></script>
</head>
<body onload="menuScreen()">
<!-- Left intentionally blank -->
</body>
</html>
Hopefully this will help you!
Well, I have my radio elements that update an iFrame with js code; and that works fine.
Then I have my button below that creates an iFrame in a HTML Division that contains a bunch o' buttons in a list, my aim is to click one of these buttons in the iFrame then have that button to update the above iFrame (the one controlled by the radio's).
How is this possible, can anyone help me? Thanks in advance.
Note: I've tried using <link rel="import" href="parentpage.html"> to import its ID's (if it does that?) then tried using JS to update it that way, to no avail.
What it looks like (layout wise)!
A simple way to do so is to get the button inside the iframe and set the event onclick like this
$(document.getElementById('iFrame2').contentWindow.document.getElementById("iFrame2Button")).click
(function ()
{
$("#iFrame1").attr('src','tests.php');
})
Assuming all the frames are in the same domain, this can be done like this:
<html>
<head>
<title>Main Page</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript">
var change_iframe1_src = function(new_src) {
$("#iframe1").attr('src', new_src);
}
</script>
</head>
<body>
<!-- frame for which we will change src attribute -->
<iframe id="iframe1" src="" width="400" height="200" border="1"></iframe>
<!-- frame which includes your iframe2 with the buttons-->
<iframe src="iframe.html" width="200" height="200" border="1"></iframe>
</body>
</html>
Now in the iframe2 file attach a click handler for your buttons that should change the src attribute of the iframe1 by calling a function defined in the main page.
Example:
<html>
<head>
<title>iFrame 2</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
$("button").click(function(e) {
e.preventDefault();
// call function in a parent frame - IMPORTANT LINE BELOW :)
parent.window.change_iframe1_src(this.rel);
})
})
</script>
</head>
<body>
<button rel="iframe3.html">Change iframe src to iframe3.html</button>
<button rel="iframe4.html">Change iframe src to iframe4.html</button>
</body>
The links in the iframe 2 page call the function which is defined in the parent window (the main page / the window which embeded the iframe2 page itself). That function (change_iframe1_src in this example) takes one argument which is a new url.
The src attribute of the frame #iframe1 (your first frame) will be changed to this url.
Again, this works as long as all the frames are in the same domain.
Hope it helped :) Source
Let me explain the purpose of this. I'm using some CMS and I'm trying to customize it with php scripts of my own that I embedded to the home page with IFRAME. My php script gives back some links which I would like to open outside that IFRAME - as a part of some other CMS block on the homepage. The idea is to target (from my php script) the div of that CMS block which is already showing some data. Is that possible?
If you need to access <div> or any other element of parent window from its child iframe
USE:
var elem=window.parent.document.getElementById('target');
inside <script> tag of iframe's document.
ex.
file: index.html (Give any name).
<html>
<body>
<div id="div_to_use_from_parent">Blah!</div>
<iframe src="xyz.php" width="xx" height="xx"></iframe>
</body>
</html>
file: xyz.php (same as src of iframe)
<?php
echo<<<html
<html>
<head>
<script type="text/javascript">
function do_blah(){
var elem=window.parent.document.getElementById('div_to_use_from_parent');
elem.innerHTML="iframe changed My Content!";
}
</script>
</head>
<body onLoad="do_blah();">
This is iframe
</body>
</html>
html;
?>
OR
if you need to access element in iframe from parent window
USE:
var iframe = document.getElementById('idOfIframe');
var frame = iframe.contentDocument || iframe.contentWindow.document;
var yourDiv= frame.getElementById('div_you_want');
inside <script> tag of parent window's document.
ex.
file: index.html (Give any name).
<html>
<head>
<script type="text/javascript">
window.onload=function(){
var iframe = document.getElementById('idOfIframe');
var frame = iframe.contentDocument || iframe.contentWindow.document;
var elem= frame.getElementById('div_from_iframe');
elem.innerHTML+="<br /> And Parent window added this!";
};
</script>
</head>
<body>
<div id="div_to_use_from_parent">Blah!</div>
<iframe src="xyz.php" width="xx" height="xx"></iframe>
</body>
</html>
file: xyz.php (same as src of iframe)
<?php
echo<<<html
<html>
<body>
<div id="div_from_iframe"> This div from iframe</div>
</body>
</html>
html;
?>
parent window is the one in which original html(index.html) document along with your iframe(xyz.php) resides.
Hope it helps :-)!
var iframe = document.getElementById('idOfIframe');
var frame = iframe.contentDocument || iframe.contentWindow.document;
var yourDiv= frame.getElementById('div_you_want');
From the page running inside the <iframe> you can refer to the parent page as window.parent, and perform actions as you normally would.
parent.document.getElementById('target_div').innerHTML = 'New content.';
Note JavaScript's cross-domain restrictions apply. You can only do that if both pages belong to the same domain.
In case of links, you can include to your <a> tags the attribute target="_parent", or set it as base target to apply to all links.
<head>
...
<base target="_parent">
</head>
You can also target a link to another iframe, all you have to do is set a name="iframe_name" to it and set target="iframe_name" to all links that should open in that area.
I am trying to figure out how to retrieve the full (that means all data) HTML page source from an <iframe> whose src is from the same originating domain as the page that it is embedded on. I want the exact source code at any given time, which could be dynamic due to Javascript or php generating the <iframe> html output. This means AJAX calls like $.get() will not work for me as the page could have been modified via Javascript or generated uniquely based on the request time or mt_rand() in php. I have not been able to retrieve the exact <!DOCTYPE> declaration from my <iframe>.
I have been experimenting around and searching through Stack Overflow and have not found a solution that retrieves all of the page source including the <!DOCTYPE> declaration.
One of the answers in How do I get the entire page's HTML with jQuery? suggests that in order to retrieve the <!DOCTYPE> information, you need to construct this declaration manually, by retrieving the <iframe>'s document.doctype property and then adding all of the attributes to the <!DOCTYPE> declaration yourself. Is this really the only way to retrieve this information from the <iframe>'s HTML page source?
Here are some notable Stack Overflow posts that I have looked through and that this is not a duplicate of:
Javascript: Get current page CURRENT source
Get selected element's outer HTML
https://stackoverflow.com/questions/4612143/how-to-get-page-source-using-jquery
How do I get the entire page's HTML with jQuery?
Jquery: get all html source of a page but excluding some #ids
jQuery: Get HTML including the selector?
Here is some of my local test code that illustrates my best attempt so far, which only retrieves the data within and including the <iframe>'s <html> tag:
main.html
<html>
<head>
<title>Testing with iframe</title>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
function test() {
var doc = document.getElementById('iframe-source').contentWindow.document;
var html = $('html', doc).clone().wrap('<p>').parent().html();
$('#output').val(html);
}
</script>
</head>
<body>
<textarea id="output"></textarea>
<iframe id="iframe-source" src="iframe.html" onload="javascript:test()"></iframe>
</body>
</html>
iframe.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html class="html-tag-class">
<head class="head-tag-class">
<title>iframe Testing</title>
</head>
<body class="body-tag-class">
<h2>Testing header tag</h2>
<p>This is <strong>very</strong> exciting</p>
</body>
</html>
And here is a screenshot of these files run together in Google Chrome version 27.0.1453.110 m:
Summary
As you can see, Google Chrome's Inspect element shows that within the <iframe> the <!DOCTYPE> declaration is present, so how can I retrieve this data with the page source? This question also applies to any other declarations or other tags that are not contained within the <html> tags.
Any help or advice on retrieving this full page source code via Javascript would be greatly appreciated.
Here is a way to build it from the doctype, seems to work for html 4 and 5, I didn't test for stuff like svg.
<html>
<head>
<title>Testing with iframe</title>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
function test() {
var d = document.getElementById('iframe-source').contentWindow.document;
var t = d.docType;
$('#output').val(
"<!DOCTYPE "+t.name+
(t.publicId? (" PUBLIC "+JSON.stringify(t.publicId)+" ") : "")+
(t.systemId? JSON.stringify(t.systemId) :"")+
">\n" + d.documentElement.outerHTML );
}
</script>
</head>
<body>
<textarea id="output"></textarea>
<iframe id="iframe-source" src="iframe.html" onload="test()"></iframe>
</body>
</html>
this also uses HTML.outerHTML to make sure you get any attribs on the documentElement.