I'm pulling a bit of html and css from a database, and it happens to contain a bit of css wrapped in a style tag. I then set some innerhtml to the string variable and display it.
The html is rendered properly, but ie will not display the content with the css - of course firefox will. Below is an abbreviated example of the code
var outputString = '<style type="text/css">.fontRed{color:red;}</style><span class="fontRed">red</span>'
I then set it to the innerHTML
document.getElementById('bilbo').innerHTML = outputString;
This displays properly (the color red) in FF, however does not in IE.
Is there a character I need to escape for IE? The rest of the html works, and even inline styles work correctly in IE.
Any assistance would be most welcome.
Thanks
Try this Approach .. Tested in IE7 and above
// Create the Style Element
var styleElem = document.createElement('style');
styleElem.type = 'text/css' ;
var css = '.fontRed{color:red;}' ;
if(styleElem.styleSheet){
styleElem.styleSheet.cssText = css;
}
else{
styleElem.appendChild(document.createTextNode(css));
}
// Append the Style element to the Head
var head = document.getElementsByTagName('head')[0] ;
head.appendChild(styleElem);
// Append the span to the Div
var container = document.getElementById('bilbo');
container.innerHTML = '<span class="fontRed">red</span>' ;
Check FIDDLE
Append the <style type="text/css">.fontRed{color:red;}</style> to the head tag first.
Just put <body> at the start of the output string. i.e.
document.getElementById('bilbo').innerHTML = '<body>' + outputString;
See http://jsfiddle.net/ScEZ4/1/ for a working demo.
Tested and working IE6, IE7, IE8, IE9, FF16, Chrome22, Opera12
Related
I created a word counting function and found a discrepancy. It produced different results counting the text words in html depending on if the element the html is enclosed in is part of the document.body or not. For example:
html = "<div>Line1</div><div>Line2<br></div>";
document.body.insertAdjacentHTML("afterend", '<div id="node1"></div>');
node1 = document.getElementById("node1");
node1.style.whiteSpace = 'pre-wrap';
node1.innerHTML = html;
node2 = document.createElement('div');
node2.style.whiteSpace = 'pre-wrap';
node2.innerHTML = html;
The white-space: pre-wrap style is applied so that the code in the html variable is rendered, in terms of line-breaks, consistently across browsers. In the above:
node1.innerText // is "Line1\nLine2\n" which counts as two words.
node2.innerText // is "Line1Line2" which counts as only one word.
My word count function is:
function countWords(s) {
s = (s+' ').replace(/^\s+/g, ''); // remove leading whitespace only
s = s.replace(/\s/g, ' '); // change all whitespace to spaces
s = s.replace(/[ ]{2,}/gi,' ')+' '; // change 2 or more spaces to 1
return s.split(' ').filter(String).length;
}
If I then did something like this in the Web Console:
node1.after(node2);
node2.innerText // is changed to "Line1\nLine2\n" which counts as two words.
My questions are:
Why is the white-space: pre-wrap style not being applied to node 2.innerText before it is inserted into the document.body?
If node 2 has to be a part of document.body in order to get a white-space: pre-wrap style node 2.innerText value, how do I do that without having to make node 2 visible?
I'm curious. When I crate a node element with createElement, where does that node element reside? It doesn't appear to be viewable in a Web Console Inspector inside or outside of the <html> tag and I can't find it in the document object.
This tipped me off that the discrepancy was something to do with if the node element being in the document.body or not: javascript createElement(), style problem.
Indeed, when the element is attached to the DOM, Element.innerText takes the rendered value into account - you can say, the visible output. For non-attached elements, there is no rendering. The CSS properties exist but are not executed.
If you want consistent results between attached and non-attached elements, use Element.textContent.
For more information, see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText
In follow-up to my question above, I needed to count the words in html text strings like this: <div>Line1</div><div>Line2<br></div> where the word count matched what it would be if that html was rendered in the displayed DOM
To summarize what others have said, when you create an element using createElement it isn’t inserted into the DOM yet and can’t be found when inspecting the DOM. Before the element is inserted into the DOM, the CSS properties exist but are not executed, so there is no rendering. When the element is inserted into the DOM, the CSS properties are executed, and the element is rendered according to the CSS.
Here's the html-string-to-rendered-html-text function I ended up using. This function strips the html tags but retains the "white space" so that the words can then be counted (with consistency across browsers, including IE 11).
var html = "<div>Line1</div><div>Line2<br></div>";
// Display the html string
var htmlts = document.getElementById("htmlts");
htmlts.innerText = html;
// Display a DOM render of the html string
var node1 = document.getElementById("node1");
node1.style.whiteSpace = 'pre-wrap';
node1.innerHTML = html;
// Display the innerText of the above DOM render
var node1ts = document.getElementById("node1ts");
node1ts.innerText = node1.innerText;
// Display the results of the htmlToText function
var node2ts = document.getElementById("node2ts");
node2ts.innerText = htmlToText(html);
// Adapted from https://stackoverflow.com/a/39157530
function htmlToText(html) {
var temp = document.createElement('div');
temp.style.whiteSpace = 'pre-wrap';
temp.style.position = "fixed"; // Overlays the normal flow
temp.style.left = "0"; // Placed flush left
temp.style.top = "0"; // Placed at the top
temp.style.zIndex = "-999"; // Placed under other elements
// opacity = "0" works for the entire temp element, even in IE 11.
temp.style.opacity = "0"; // Everything transparent
temp.innerHTML = html; // Render the html string
document.body.parentNode.appendChild(temp); // Places just before </html>
var out = temp.innerText;
// temp.remove(); // Throws an error in IE 11
// Solution from https://stackoverflow.com/a/27710003
temp.parentNode.removeChild(temp); // Removes the temp element
return out;
}
<html lang="en-US">
<body>
HTML String: <code id="htmlts"></code><br><br>
Visible Render of HTML String (for comparison): <div id="node1"></div><br>
Visible Render Text String: <code id="node1ts"></code><br>
Function Returned Text String: <Code id="node2ts"></code><br>
</body>
</html>
If you prefer to have the temporary element insert inside the body element, change document.body.parentNode.appendChild to document.body.appendChild.
As Noam had suggested, you can also use temp.style.top = "-1000px";.
To answer my curiosity question: before the element is "inserted into the DOM" it appears to be in a Shadow DOM or Shadow Dom-like space.
I'm building an html preview tool inside a small project and I'm trying to find the best way to place html and the css that will style that html inside an iframe.
I'm able to create the iframe and place the html contents of my div inside. So far that seems to be working correctly in this fiddle
$(function() {
var $html = $("#html").html();
var $frame = $('<iframe>');
$('body').html( $frame );
var doc = $frame[0].contentWindow.document;
var $framehtml = $('html',doc);
$framehtml.html($html);
});
But how do I add css to the head of that iframe? For example, adding the class .mobile you see in the fiddle to the head of the iframe so the image is hidden when the iframe reaches a width of 500px?
EDIT: I don't want to inject a css style sheet. I'd rather create a tag in the head and place the css you see in the fiddle.
#FRAN and #APAD1 were right, this is a duplicate. I was able to use those answers to create my own with this updated fiddle
var $head = $("#myframe").contents().find("head");
$head.append($("<style/>",
{type: "text/css" }));
var $style = $("#myframe").contents().find("style");
$style.append($css);
I have a page with 3 DIV's on them, one with a header, one with a selection-list and the third will get filled with data once something is selected in the selection-list.
When something is selected, code like
document.getElementById("fields").innerHTML='<object type="text/html" data="' + fieldsPage + '" style="width:70%;height:90%" ></object>';
is executed, filling the DIV with the contents of another (generated) page.
I can view the page fine in Chrome and IE, but...
...when I search for something, Chrome finds it even in the DIV filled through innerHTML, but IE doesn't.
IE seems to only search in the header and selection-list DIV's.
Any suggestions to get IE to search the whole page as well?
Try this:
var node = document.createElement ("object");
node.type = "text/html";
node.data = fieldsPage;
node.style.width = "70%";
node.style.height= "90%";
document.getElementById("fields").innerHTML = "";
document.getElementById("fields").appendChild(node);
Good luck.
In the code included below, the script is toggling a div on and off. The .style
code, controls the background color of the the parent element of the div being toggled
on and off. The code works in Opera but not in Chrome, and I haven't been able to
research (search) a solution.
I can of course move on and write other code and achieve what I need, but this has my
curiosity up now.
function CheckOutOpn(){
var Inny = document.getElementById("RightPaneASxOrderForm");
MVxCheckOutForm();
CDxButtonOpnChkOut();
MVxCLOSExBttnChkout();
Inny.style = "background-color:#332223;";
}
function CLOSExCheckOut(){
var Inny = document.getElementById("RightPaneASxOrderForm");
MVxButtonOpnChkOut();
CDxCLOSExBttnChkout();
CDxOrderFormItself();
Inny.style = "background-color:#33B32E;";
}
I think you should be using:
Inny.style.backgroundColor = "#332223";
https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement.style
... Except in Opera, styles can not be set by assigning a string to the
(read only) style property, as in elt.style = "color: blue;". This is
because the style attribute returns a CSSStyleDeclaration object.
If you want to set the style of an element textually, you need to use either
Inny.style.cssText="background-color:#33B32E"
or
Inny.setAttribute("style","background-color:#33B32E")
or you can set the properties directly:
Inny.style.backgroundColor = "#33B32E";
I think this will work for you fine. only mistake you are doing is, when you are adding the css properties to the element.
function CheckOutOpn(){
var Inny = document.getElementById("RightPaneASxOrderForm");
MVxCheckOutForm();
CDxButtonOpnChkOut();
MVxCLOSExBttnChkout();
Inny.style.backgroundColor = "#332223";
}
I want to set up css display property in javascript code:
var div = document.createElement('div');
div.innerHTML = content;
div.childNodes[0].style.display = '';
It works in IE but doesn't in FF. It says "style" is undefined for element div. How can I do it in FF?
Thanks
What is content? If it starts with white space, then there will be a TextNode as the first child and they don't have style properties (HTMLElementNodes do).
You can either:
loop over the children until you either get to the end or find an HTMLElementNode
strip the whitespace from the start of content
switch to using createElement and friends instead of innerHTML
This should also work:
var div = document.createElement('div');
div.innerHTML = content;
div.childElementCount && div.firstElementChild.style.display = '';