If I have the following line in html:
<span></span> wtf
and then I run the jQuery statement:
$("span").html("test");
It ends up looking like "testwtf" instead of "test wtf". Is there anything I can do about this without changing the html?
This happens because IE is interpreting the space in <span></span> wtf to be a leading space, and omits it (and interprets the HTML as <span></span>wtf). Because IE is interpreting the HTML differently than other browsers, I don't think there's much you can do without changing the HTML, except doing a workaround like
$CONTAINER.html('<span>test</span> wtf')
or an even more extreme workarounds such as
if (jQuery.browser.msie) $("span").html("test "); else $("span").html("test");
Edit: Preliminary testing shows that $("span").html("test "); by itself is also sufficient.
Related
If I grab some html from one element, then attempt to assign it as the text content of another element, newlines are not preserved (at least not in the latest Firefox and Chromium).
So, for example, the follow code (with sensible html) produces output where the newlines are replaced by spaces. Well, except the alert, which works as expected.
$("#info").data("html", $("#info").html());
$("#jquery").text($("#info").data("html"));
document.getElementById("javascript").textContent = $("#info").data("html");
$("#alert").click(function() { alert($("#info").data("html")) });
Here's a running example: http://jsfiddle.net/76S7z/2/
There should be some method of setting the html of one element as the text of another while preserving newlines properly.
Is this possible with "text" or "textContent"? Is there an alternative way to do this? Is there a simple workaround? A less than simple workaround?
As you've already determined, Web browsers don't normally render newline characters \n as line breaks. If you're resistent to adding the line break element <br />, you can use the white-space CSS property with the value pre-line, which will:
Sequences of whitespace are collapsed. Lines are broken at newline characters, at <br>, and as necessary to fill line boxes.
Be sure to check the property's compatibility tables before using.
<div style="white-space: pre-line;">
Look
at
these line breaks!
</div>
Here's a JSFiddle example.
I encountered this "bug" in the latest verison of firefox and I don't know what causes this behavior and which is the correct result.
HTML
<div><h1 id="heading">First Title</h1></div><div><h1>Second Title</h1></div>
JavaScript
var allDivNodes = document.getElementsByTagName("div");
console.log(allDivNodes[0].childNodes);
console.log(allDivNodes[1].childNodes);
console.log(allDivNodes[0].childNodes.length);
console.log(allDivNodes[1].childNodes.length);
The result I get is the following:
And here is the quirk. If I add spaces in my HTML code and run the same script I get this result:
NEW HTML. JavaScript stays the same
<div>
<h1 id="heading">First Title</h1>
</div>
<div>
<h1>Second Title</h1>
</div>
New Result:
I thought that JavaScript was white space insensitive. So why does it change nodeLength from 1 to 3?
You could use children instead of childNodes, because of formatting you introduced some text nodes (Yes they are nodes with type 3 not just some whitespace) and childNodes will return all of them.
console.log(allDivNodes[0].children.length);
Or with childNodes you can loop though and ignore the ones with nodeType === 3.
Also similarly you have childElementCount as well which will give you the childElement count and will ignore text nodes.
I thought that JavaScript was white space insensitive. So why does it change nodeLength from 1 to 3?
Firefox is behaving correctly.
This isn't a JavaScript issue. The DOM counts "whitespace only" areas as text nodes, and so the JavaScript is correctly returning all child nodes it finds.
It was older IE that behaved differently, where such whitespace only areas would be ignored. This has been corrected since IE9.
Basically, anything that appears in the page is represented as a DOM node.
I personally prefer to compress my HTML. It not only reduces the download time, but it also makes the DOM smaller with less to occupy memory, and fewer undesired nodes to work around.
I have a js replace function to replace text next to two radio buttons on a pre set form.
Script is as follows.
document.body.innerHTML=document.body.innerHTML.replace("Payment by <b>Moneybookers</b>
e-wallet<br>","");
document.body.innerHTML=document.body.innerHTML.replace("Maestro, Visa and other credit/debit cards by <b>Moneybookers</b>","Pago con Diners Club, Mastercard o Visa");}onload=x;
The script works fine in Chrome and Firefox, however, the script is not actioned in Explorer.
I believe it has something to do with there being , / - within the text I am replacing? When I use the function to replace text with no , / - in the text - it works fine in explorer, however, for example when I try to replace text.. - "Maestro, Visa and other credit/debit cards by Moneybookers" this does not work in explorer.. I'm assuming because of the coma and forward slash. Honestly I've tried everything but just can not get this to work. Any help would be greatly appreciated!!
Not sure whether it's related (I'm a Mac user without IE) but you shouldn't use multiline strings. Use \n instead.
What is returned by innerHTML varies from one browser to an other, because there is no standard about it (the content will be the same, but the way it's displayed can be different). Doing replace like that is likely to fail on some browser. You should just take an other approach to do your replace.
A better approach would be to wrap the text you want to replace with a span, this way you can more easily target the content you want to replace.
<span id="thatFirstThing">Payment by <b>Moneybookers</b>e-wallet<br></span>
An after you can do
document.getElementById("thatFirstThing").innerHTML = "";
P.S.: Doing innerHTML replace on the body also has a huge side-effect. Since you are replacing the content of your hole page. All the event handler that where bind on your page will disappear.
Edit: If you can't modify the HTML page, it's a little bit more tricky, because the DOM is not well adapted to do such thing. What you could do is to target parent element by navigating through the DOM with document.getElementById and childNodes. And once you have your parent element just write the new content you want, without doing replace.
In the end it would look something like this :
document.getElementById("someSection").childNodes[0].childNodes[1].childNodes[0].innerHTML = "";
I'm loading a string via AJAX that reads like
<style>[some definitions]</style>
<h1>Lots of Markup</h1>
<p>follows here</p>
Using Webkit/Gecko everything works as expected — the markup is inserted, styles are applied. In IE (8) though the style-definitions are ignored. Actually, if you use the developer tools they are gone.
You can see in this JS-Fiddle that it doesn't work: http://jsfiddle.net/J4Yzr/
Also, I've seen that trick that you create a temporary DOM-Object, set it's innerHTML to your markup and extract your markup as DOM-Objects from your temporary element. That doesn't work with style tags (if I did it right, I'm using prototypeJS):
var text = '<style>h1{color:red;}</style> style added',
el = new Element('div').update(text);
console.log(el.firstChild);
//is a HTMLStyleElement in Webkit but a [object Text] in IE
Does anyone have a suggestion how to properly apply the <style> in IE if you get it from such a string?
I had the same problem, so I tried your solution, but guess what? When I stripped the out after rendering markup retrieved via Ajax, the tags disappeared from the DOM! Back to square one.
So my solution is to prepend this instead:
<hr style='display:none'/>
Which did the trick nicely. Thank you so much for solving this issue.
Ok, it's crazy. Add a <br/>-Tag in front of your string and it works in Internet Explorer.
<br/><style>[some definitions]</style><h1>Lots of Markup</h1>
You don't even need to create that temporary DOM-Object to insert code into. Just append it in your site.
What I'm doing now it insert the code with a <br/>-Tag and remove the <br/> afterwards. It's messy but it works.
I'm trying to use jQuery to format code blocks, specifically to add a <pre> tag inside the <code> tag:
$(document).ready(function() {
$("code").wrapInner("<pre></pre>");
});
Firefox applies the formatting correctly, but IE puts the entire code block on one line. If I add an alert
alert($("code").html());
I see that IE has inserted some additional text into the pre tag:
<PRE jQuery1218834632572="null">
If I reload the page, the number following jQuery changes.
If I use wrap() instead of wrapInner(), to wrap the <pre> outside the <code> tag, both IE and Firefox handle it correctly. But shouldn't <pre> work inside <code> as well?
I'd prefer to use wrapInner() because I can then add a CSS class to the <pre> tag to handle all formatting, but if I use wrap(), I have to put page formatting CSS in the <pre> tag and text/font formatting in the <code> tag, or Firefox and IE both choke. Not a huge deal, but I'd like to keep it as simple as possible.
Has anyone else encountered this? Am I missing something?
That's the difference between block and inline elements. pre is a block level element. It's not legal to put it inside a code tag, which can only contain inline content.
Because browsers have to support whatever godawful tag soup they might find on the real web, Firefox tries to do what you mean. IE happens to handle it differently, which is fine by the spec; behavior in that case is unspecified, because it should never happen.
Could you instead replace the code element with the pre? (Because of the block/inline issue, technically that should only work if the elements are inside an element with "flow" content, but the browsers might do what you want anyway.)
Why is it a code element in the first place, if you want pre's behavior?
You could also give the code element pre's whitespace preserving power with the CSS white-space: pre, but apparently IE 6 only honors that in Strict Mode.
Btw I don't know if it is related but pre tags inside code tags will not validate in strict mode.
Are you using the latest jQuery ?
What if you try
$("code").wrapInner(document.createElement("pre"));
Is it any better or do you get the same result ?
As markpasc stated, a PRE element inside CODE element is not allowed in HTML. The best solution is to change your HTML code to use <pre><code> (which means a preformatted block that contains code) directly in your HTML for code blocks.
You could use html() to wrap it:
$('code').each(function(i,e)
{
var self = $(e);
self.html('<pre>' + self.html() + '</pre>');
});
As mentioned above, you'd be better off changing your html. But this solution should work.