HTML 5, darum ist der parentNode das body element

Die Arbeit an einem JavaScript zeigte mir einmal mehr, dass man immer dazu lernen kann. So dachte ich doch, dass ich HTML grundsätzlich eigentlich schon ziemlich gut kenne. Aber grundsätzlich eigentlich reicht manchmal eben nicht – offensichtlich.

Für mein JavaScript habe ich mir eine Test HTML Datei zusammengeschrieben. Es ging um einen Parser in JavaScript, der Texstellen finden kann. Dazu durchsucht der Parser das DOM des HTMLs und durchsucht die Texte der Nodes. Mein Parser brachte aber an einer Stelle ein unerwartetes Ergebnis und ich suchte lange im JavaScript-Code nach dem Fehler. Etwas unerwartet lag das Problem dann aber nicht im JavaScript Code, sondern in der HTML Syntax.

HTML 5 Testdatei

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Parser Test</title>
    <meta name="description" content="parser Test">
    <meta name="author" content="neisgei">
</head>

<body>
<p>erster absatz <b>PARSE_1</b> absatz ende</p>
<p>zweiter absatz PARSE_2 etwas text 
<div>PARSE_3</div> etwas text PARSE_4 absatz ende</p>
<p>dritter absatz PARSE_5 absatz ende</p>
</body> 
</html>

Mein Parser sucht nun die PARSE Texte und liefert für die gefundenen Stellen den parentNode.

Fund-Text parentNode
PARSE_1 b
PARSE_2 p
PARSE_3 div
PARSE_4 body
PARSE_5 p

Wait, what? Wieso bringt mein JavaScript bei PARSE_4 body als parentNode?

Ich schicke das HTML durch den Validator der w3.org.

Ok, habe ich leider nicht direkt gemacht. Denn zuerst dachte ich natürlich, dass es am komplexen Script lag. Also beschloss ich nach Stunden der Suche, dass es möglicherweise doch am HTML und nicht am Script liegen könnte.

Validierung

Validator

Frei übersetzt: Warum sieht der ein Endtag ohne Anfangstag?

Jetzt muss ich sagen, dass die ursprüngliche Test-HTML Datei mit der ich in das Problme lief, doch verschachtelter und mit mehr Text und Tags waren, als das Beispiel oben. Vielleicht kommt man mit obigen, minimalistischem HTML eher auf die Idee, was falsch laufen könnte. Jedenfall sah ich auch nach langem Suche immer noch nicht, wo ich ein Anfangs- p Tag vergessen haben sollte. Aber ich wusste immerhin auch, dass das Script nicht primär schuld sein konnte.

Also mal googlen, aber nach was genau? Nach p-Tag vergessen… ? Dann halt mal was mit DOM, P und DIV. Und siehe da, ziemlich schnell kam ich auf die Lösung auf stackoverflow.

DIV in P ist nicht erlaubt

Die zugegebenermassen grosse Erstaunung; ein DIV ist in einem P Tag nicht erlaubt. Die grosse Erstaunung deshalb, weil ich doch sagen würde, dass ich im Bereich des “BOX-Layouting” oft DIV verwende und ich bin mir sicher, dass da oft ein DIV innerhalb eines P vorgekommen ist in der Vergangenheit. Doch nie hatte ich in den Browsern Darstellungsprobleme, deshalb hat mich das auch nicht gekümmert.

Aber die W3C Recommondations sagen es deutlich: ein Block Element darf kein anderes Block Element beinhalten.

Ist doch klar! Du würdest auch nie

<h1>Ein titel<p>auf zwei Zeilen</p><h1>

machen… Hoffentlich!

Du machst das nicht, weil Du eigentlich weisst, dass ein Block Element kein anderes Block Element beinhalten soll. Dann schauen wir doch einmal, was denn Block Elemente sind.

HTML Block Elemente

  • <div>
  • <h1> – <h6>
  • <p>
  • <form>

Und diese werden nie verschachtelt, dann gibt es auch valide HTML Syntax und das JavaScript bringt auch keine unverständlichen parentNodes.

Abschliessend noch die Erklärung, warum body das parentNode war:

Aus dem ungültigen HTML

<body>
    <p>
        zweiter absatz PARSE_2 etwas text 
        <div>PARSE_3</div> 
        etwas text PARSE_4 absatz ende
    </p>
</body>

wird im Browser – und somit für das JavaScript beim DOM parsen – folgendes HTML

<body>
    <p>
        zweiter absatz PARSE_2 etwas text 
    </p>
    <div>PARSE_3</div>
    etwas text PARSE_4 absatz ende</p>
<body>

Der eingerückte Code zeigt nun auch direkt auf, dass nun eben body der parentNode von PARSE_4 wird. Der Absatz wird vom Browser vor dem DIV geschlossen und nach dem DIV verbleibt dann das End- P Tag, was dann letztlich zum invaliden HTML führt. Der Browser ist sehr Fehlertolerant und zeigt das HTML an. Für das DOM befindet sich aber der Text vom Absatz-Ende nicht mehr innerhalb eines P Tags, sondern nun direkt im BODY.

Und wenn Du nun denkst “MIR war das klar, was ist der neisgei nur für ein HTML Depp…” dann frage ich Dich; “hast Du wirklich, wirklich noch nie z.B. innerhalb eines FORM Tags P, oder DIV verwendet? Oder in einem P Absatz ein Div für ein PopUp-Layer platziert…? Wirklich? Bist Du Dir da so ganz sicher? ;-)

Leave a Reply

  

  

  

*