Rishi P
Rishi P

Reputation: 287

Weird javascript

I 've got a very interesting thing with an html here.

<head>
<script language="Javascript">
  var str="me&myhtml";
  function delimit(){
    document.write(str);
    document.write("<hr>");
  }
</script>
<body onload="delimit()">

You see 'me&myhtml' with a line beneath. However, if you comment //document.write("<hr>"); then you just see 'me', which is weird.

Thing is, javascript normally doesn't read '&', but rather interprets as a command. However, if you have any document.write() with at least 6 characters, or a 'br', or 'hr', then it displays '&' as it is.

Any ideas?

Upvotes: -1

Views: 291

Answers (4)

bobince
bobince

Reputation: 536379

I just wanted to know why this is happening.

Well, the browser doesn't yet know whether your &myhtml is an entity reference you haven't finished writing yet, or just broken code it will have to fix up. For example you can say:

document.write('&eac');
document.write('ute;');

(Of course there is no entity reference like &myhtmlpotato; that you could be referring to, but the parser doesn't know that yet.)

If you let the parser know there's no more bits of entity reference coming, by document-writing something that couldn't possibly be in an entity reference, such as a <tag>, or spaces, it'll give up and decide your code was simply broken, and fix it.

Normally the end of the page would be a place where this would happen, but you don't have an end of the page, because the script isn't doing what you think it's doing.

Instead of calling document.write() during the original page loading process when it can write some content to your current page, you're calling it in the onload, by which time the document is completely loaded and you can't add to it. In this state, calling document.write() actually calls document.open() implicitly, destroying the current page and starting a new one, to which you then write ‘my&myhtml’. That new page you have opened stays open and not fully loaded until you call document.close() to tell it you aren't going to write any more to it. At that point your partial entity reference will be resolved as bad markup and fixed.

Upvotes: 1

Grant Wagner
Grant Wagner

Reputation: 25931

If there is no HTML tag after &myhtml JavaScript or the HTML rendering engine probably interprets it as an unrecognized or incomplete entity (lacking an ending ;) and does not render it. If you follow me&myhtml with an HTML tag, then JavaScript or the HTML rendering engine recognizes that &myhtml is not an incomplete entity because it is followed by an HTML tag instead of a ;.

It doesn't matter what HTML tag you follow the string with, <a> or <p> work just as well as <br>.

The behavior is not consistent across all browsers. IE 6, 7 & 8 and Firefox 2, 3 & 3.5 behave the way you describe, Safari for Windows 3 & 4 render nothing when you comment out the second document.write() or do something like document.write("abc");. Opera 9.64 & 10b3 render the text correctly regardless of the content of the second write().

Note that using document.write() in the onload event without writing out correctly formatted and valid HTML (complete with doctype and <html>, <head>, etc) is probably a bug anyway. Note the problem does not manifest itself if you do:

<html>
<head>
<script>
function delimit() {
    document.write('me&myhtml');
}
</script>
</head>
<body>
<script>
delimit();
</script>
</body>
</html>

To answer your question, it is a bug in either the implementation of a specification, or an undefined part of a specification that each browser implements differently. What you are doing is slightly incorrect, the outcome of that slightly incorrect code is not defined and it can not be relied on to behave consistently across all of the major browsers in use today. What you are doing should be avoided.

Upvotes: 10

Rudd Zwolinski
Rudd Zwolinski

Reputation: 27581

It probably has to do with the fact that & is essentially an escaping character in HTML. If you want to write out an ampersand to the page, you should use &amp;

Upvotes: 0

Scoregraphic
Scoregraphic

Reputation: 7200

Try str = "me&amp;myhtml";

Upvotes: 3

Related Questions