Discussion: js write a <hr>
Afficher un message
Vieux 11/09/2007, 16h29   #10
GreyWyvern
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: js write a <hr>

And lo, Blinky the Shark didst speak in alt.www.webmaster:

> Can't for the life of me figure out how to get a hr into a js write.
>
> http://blinkynet.net/humor/index.html
>
> I'd like a *scripted* <hr> just before the first line created by the
> fist little script do that it separates the quote of the day from the
> page intro above it. The reason I want it to be part of the script is
> so if scripts are disabled and the separator isn't needed, it's not
> rendered. (The nonscripted <hr> *after* the quote of the day will be
> all the separation I need between the intro and the list.)
>
> I've been able to make this work just fine with "<hr />" being the first
> element in the first document.write:
>
> document.write("<hr />" + "foo")
>
> But validation fails with a you-can't-use-a-<hr>-there error.


/me boggles at all the other responses in this thread.

XHTML is not just HTML with a few fancy markup changes. The way the
markup is *interpreted* changes as well. XHTML is meant to be valid XML
and thus must follow all the rules as XML.

One of the rules is that you can't just include text containing angle
brackets or ampersands without them being interpreted as markup and
entities. Unless you comment it out, or strictly define it as CDATA
(character data), the XML parser will assume it is PCDATA (parsed
character data), or IOW: markup.

The element which which you're having problems is this one:


<script type="text/javascript">
document.write("<hr \/>" + "Today's alleged Yogi-ism:")
</script>


If this were normal HTML, the parser would recognise the script element as
special and switch to the JS parser for all the contents. The XML parser
doesn't do this. In XHTML, the script element is *not* special and
elements found inside it are interpreted as actual elements, whether they
are inside document.write's or not.

So, in order to get it to validate, you need to tell the parser that
what's inside the script element is special. You can do this in one of
two ways, but there are caveats about both.

1) Simply use SGML comments to hide the code:


<script type="text/javascript"><!--
document.write("<hr \/>" + "Today's alleged Yogi-ism:")
--></script>


There are two issues with this though. The first is, though browsers you
view this in will interpret this bit of code the way you think it should
work, that's only because you are serving XHTML code to the HTML tag-soup
parser by using the text/html MIME-type. *Technically* the XML parser is
allowed to ignore *anything* within SGML comments, *even code*. So
interpreted as real XML, the above snippet is entirely equivalent to:


<script type="text/javascript"></script>


The second issue is that the double hyphen is a special sequence within
SGML comments which tell it the comment is ending. Unfortunately, the
double hyphen is also used in Javascript as the decrement operator (x--)..
So commenting out your code this way precludes you from using the
decrement operator at all or else some of your code may appear as text,
and/or your document will not validate. This second issue affects plain
HTML as well.

2) Use the XML <![CDATA[ ... ]]> structure to mark the boundaries of your
code.


<script type="text/javascript"><![CDATA[
document.write("<hr \/>" + "Today's alleged Yogi-ism:")
]]></script>


This is the preferred way to do things in XML, but it won't work in your
document. Why not? Because you are serving it with a text/html
MIME-type. This means that markup which *should* be parsed with the XML
parser is being parsed with the HTML tag-soup parser instead. This is
precisely why, in your existing document, the JS still works, even though
the document doesn't validate as XHTML.

In order for the above to function properly in both an HTML and XHTML
context, you'd need to use a comment system like so[1]:


<script type="text/javascript"><!--//--><![CDATA[//><!--
...
//--><!]]></script>


That's pretty crazy, eh?

So, to summarize: Your markup is being delivered to the browser using the
text/html MIME-type. This allows it to render as you think it should
because the HTML tag-soup parser is being used. However, the W3C
validator is interpreting your XHTML markup as if it were served with the
correct MIME-type: application/xhtml+xml OR text/xml

This is leading to validation errors which are only errors of context.
The code is being rendered by browsers in one context, while the validator
is viewing it in another. I would recommend that if you don't yet fully
understand the difference between these two contexts, you should return to
plain HTML4, since that is exactly how you are telling browsers to
interpret your XHTML markup anyway.


One last thing to note, in XHTML sent with one of the proper MIME-type's
above, certain JS methods which have the potential to allow easy breakage
of the strict XML rules have been disabled. This includes
document.write() and also innerHTML() and its relatives. So the code you
are trying to use, even if you did try switching to the correct
MIME-types, would not even work, instead throwing JS errors.

An equivalent would be (commented to work in both text/html and text/xml):


<script type="text/javascript" id="replaceMe"><!--//--><![CDATA[//><!--
var hr = document.createElement('hr');
var thisElem = document.getElementById('replaceMe');
var parentElem = thisElem.parentNode;
parentElem.replaceChild(hr, thisElem);
parentElem.appendChild(document.createTextNode("To day's alleged
Yogi-ism:"));
//--><!]]></script>


Or the somewhat simpler to understand, but won't work in IE 5.5 and
earlier[2]:


<script type="text/javascript" id="replaceMe"><!--//--><![CDATA[//><!--
var frag = document.createDocumentFragment();
var hr = document.createElement('hr');
frag.appendChild(hr);
frag.appendChild(document.createTextNode("Today's alleged
Yogi-ism:"));
var thisElem = document.getElementById('replaceMe');
thisElem.parentNode.replaceChild(frag, thisElem);
//--><!]]></script>


More complicated, yesh. However the purpose is to enforce, as much as
possible, dynamically added code to be valid XML in itself.

If this is all too much for you to handle, then you should seriously
consider a step back from XHTML and stick with HTML. Like I said, it's
more than just a few extra rules tacked onto HTML 4.01; XHTML is an
entirely different way to parse documents.

HTML is entirely sufficient for most web documents of any kind.

> So I look at W3Schools, which I think I've seen recommended here for
> tutorials -- I'm obviously new to js.
>
> Barely into the js tute, I see:
>
> <q>
>
> A JavaScript statement like this: document.write("<h1>" + name +
> "</h1>") can write a variable text into an HTML page
>
> </q>
>
> Now if they can get a <h1> in there, why can't I get a <hr> in, using the
> same method? Yes, I tried it with and without closing tags. Validator
> won't have anything do do with it.


It is simply because you are using an XHTML DOCTYPE. The validator is
expecting you to follow the rules as if you were using one of the correct
MIME-types.

> Is there a *simple* way to do that I want? No, I'm not going to do
> twelve lines of code for one hr.


Yesh, change the DOCTYPE back to HTML 4.01. Simple.

Grey

[1] http://www.hixie.ch/advocacy/xhtml

[2] IE 5.5 and earlier do not support the DocumentFragment object.

--
The technical axiom that nothing is impossible sinisterly implies the
pitfall corollary that nothing is ridiculous.
- http://www.greywyvern.com/orca#search - Orca Search: Full-featured
spider and site-search engine
  Réponse avec citation
 
Page generated in 0,09462 seconds with 9 queries