4

How can I check that content generated by JavaScript is valid HTML? For example, the following document will pass static HTML validation (e.g. validator.nu), will not produce any JavaScript errors, and will render without complaint in a browser:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>test</title>
        <script>
            window.onload = function() {
                var text = document.createTextNode('nested anchor');
                var anchor = document.createElement('a');
                var nested_anchor = document.createElement('a');
                nested_anchor.appendChild(text);
                anchor.appendChild(nested_anchor);
                document.getElementsByTagName('body')[0].appendChild(anchor);
            };
        </script>
    </head>
    <body>
        <p>test</p>
    </body>
</html>

However, the output contains an anchor inside another anchor element, which is not valid according to the HTML5 specification. Is there any way to check for these sorts of errors?

user993096
  • 43
  • 1
  • 3
  • possible duplicate of [Making/finding html5 validator bookmarklet](http://stackoverflow.com/questions/10377840/making-finding-html5-validator-bookmarklet) – cmeeren Jul 17 '15 at 17:02

4 Answers4

3

You could output the resulting HTML as a String, embed it in a valid document and send it for validation. In your case, using jQuery var htmlText = $(anchor).html().

Or even simpler, output the whole resulting html console.log($("html").html())

solendil
  • 8,432
  • 4
  • 28
  • 29
  • Thanks. I was hoping for something a bit more "one click", but that really helps. I always forget about `console.log()`! – user993096 Oct 14 '11 at 08:14
2

A possibility is to use the Validate Local HTML feature of the Web Developer toolbar (Chrome & Firefox). This feature will use the W3 validator to validate the generated HTML.

Instead of downloading an extension, you can also use my JavaScript bookmarklet to validate the local HTML. Create a bookmark, and paste the code below at the "URL" field. Then, whenever you want to validate the local HTML, click at the bookmarklet.
The code below is stand-alone, and doesn't require any framework.

javascript:void(function(){
    var form = document.createElement("form");
    form.method = "POST";
    form.enctype = "multipart/form-data";
    form.action = "http://validator.w3.org/check";
    form.target = "_blank";

    /* Get local HTML*/
    var html = "<html>" + document.documentElement.innerHTML + "</html>";
    var post_data = {
        fragment: html,/*Settings for validator*/
        prefill: "0",
        doctype: "HTML5",
        prefill_doctype: "html401",
        group: "0",
        ss: "1",
        outline: "1"
    };
    for(var name in post_data){
        (function(){
            var t = document.createElement("textarea");
            t.name = name;
            t.value = post_data[name];
            form.appendChild(t)
        })()
    }
    document.body.appendChild(form);
    form.submit(); /* Open validator, in new tab*/
    document.body.removeChild(form);
})()
Rob W
  • 341,306
  • 83
  • 791
  • 678
  • 1
    @SalmanPK I've created an improved version, which also includes the page's doctype and other root elements. See this answer: [Making/finding html5 validator bookmarklet](http://stackoverflow.com/a/10420384/938089?making-finding-html5-validator-bookmarklet). – Rob W Jun 07 '12 at 21:14
  • Awesome. Thank you again! :) Working on a SPA and none of those chrome extensions work with dynamically generated markup :/. BTW that version is missing a `document.body.removeChild(form)` call I guess. – Samuel Katz Jun 07 '12 at 21:27
1

"Just save the html source after it has fully loaded and use that static file for validation."

I would presume if this worked that the browser would fix many issues when it takes a snap shot of the HTML from the DOM.

user2323922
  • 95
  • 1
  • 3
0

Just save the html source after it has fully loaded and use that static file for validation.

frisco
  • 1,897
  • 2
  • 21
  • 29