• Visitors can check out the Forum FAQ by clicking this link. You have to register before you can post: click the REGISTER link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below. View our Forum Privacy Policy.
  • Want to receive the latest contracting news and advice straight to your inbox? Sign up to the ContractorUK newsletter here. Every sign up will also be entered into a draw to WIN £100 Amazon vouchers!

Jquery html() issue

Collapse
X
  •  
  • Filter
  • Time
  • Show
Clear All
new posts

    Jquery html() issue

    It has taken me forever to find out what was at the root of this bug.

    Basically, I've got a containing div which is populated in the success callback i.e.

    $.ajax({
    //other stuff here
    success: function(result)
    { $('#container').html(result); }
    });

    Then in the markup I have <div id="container"/>

    What's happening is that the div is populated ok but no sibling content is rendered - only the div and its containing elements. Nothing else on the form gets rendered. I look in Firebug and it's all formed ok.

    Then, if I change <div id="container"/> to <div id="container"></div> everything works fine.

    Anyone come across this before? I appreciate it may be a schoolboy error - I'm quite new to all this asynchronous stuff.

    #2
    Originally posted by Gittins Gal View Post
    It has taken me forever to find out what was at the root of this bug.

    Basically, I've got a containing div which is populated in the success callback i.e.

    $.ajax({
    //other stuff here
    success: function(result)
    { $('#container').html(result); }
    });

    Then in the markup I have <div id="container"/>

    What's happening is that the div is populated ok but no sibling content is rendered - only the div and its containing elements. Nothing else on the form gets rendered. I look in Firebug and it's all formed ok.

    Then, if I change <div id="container"/> to <div id="container"></div> everything works fine.

    Anyone come across this before? I appreciate it may be a schoolboy error - I'm quite new to all this asynchronous stuff.
    Its the difference between an explicitly intentionally empty element and an empty element. The best advice is to never make any html explicitly empty unless its a line break...
    merely at clientco for the entertainment

    Comment


      #3
      Originally posted by eek View Post
      Its the difference between an explicitly intentionally empty element and an empty element. The best advice is to never make any html explicitly empty unless its a line break...
      Thanks.

      It is valid html though and I can't find this issue documented anywhere.

      Also, what happens when you are using certain frameworks to generate html? I'm pretty sure an aspx panel gets output as <div/> when it's empty. I'm guessing you have to specify a certain doctype or something?

      Comment


        #4
        Originally posted by Gittins Gal View Post
        Thanks.

        It is valid html though and I can't find this issue documented anywhere.

        Also, what happens when you are using certain frameworks to generate html? I'm pretty sure an aspx panel gets output as <div/> when it's empty. I'm guessing you have to specify a certain doctype or something?
        It's valid but probably doesn't mean what you think. In XHTML <div /> means <div></div> but in HTML 4 or 5 it simply means <div>

        so without a closing tag it's not valid.

        I think

        Comment


          #5
          Originally posted by Gittins Gal View Post
          It is valid html though and I can't find this issue documented anywhere.

          Also, what happens when you are using certain frameworks to generate html? I'm pretty sure an aspx panel gets output as <div/> when it's empty. I'm guessing you have to specify a certain doctype or something?
          No it isn't. As eek and Bunk say, it's to do with the difference between an element whose content model is "empty" and one that isn't.

          To clear up some terminology: in HTML, a "tag" is a piece of markup that starts with with a "<" then a "/" if it's an end tag or nothing if it's a start tag, then a tag name, then whitespace (which is optional if the tag has no attributes), then zero or more attributes separated by whitespace, then a ">". An "element" is represented by either a start tag and an end tag with some (possibly zero-length) content between them, such as <p>foo</p>, or by a single tag if - and only if - it is incapable of having content, i.e. has an empty content model, such as <br>.

          I'll ignore the id attribute in your example from here on as it isn't relevant to the matter at hand.

          The <tagname /> syntax was introduced as a way of representing HTML tags that had an empty content model in a form that is also well-formed XML, so as to produce XHTML. As hardly anybody has ever produced valid XHTML, browsers have always just treated everything as HTML. Basically, forget XHTML as it's completely irrelevant in this context.

          The problem you have is that when an HTML parser sees <div /> what it actually does is:
          1. < - right, we have the beginning of a tag;
          2. div - it's a start tag (as an end tag would begin with "/") and the tag name is "div";
          3. - a space, so after this we expect either attributes, or the ">" that denotes the end of the tag;
          4. / - an attribute named "/" - but hang on, that's an illegal character in an attribute name, so ignore that;
          5. > - the end of the start tag.


          So, as far as the HTML parser is concerned, it's seen a start "div" tag, and that tag will remain open until either:
          1. A matching end tag "</div>" is reached, closing the div;
          2. A tag (starting or ending) is reached which is not allowed inside this div (e.g. "</body>", in which case take steps to make sense of the ill-formed markup lacking an end tag for the div by closing the div;
          3. The end of the document (or end of the input, if parsing a fragment of markup) is reached, in which case take steps to make sense of the ill-formed markup lacking an end tag for the div by closing the div.


          So your <div /> is never closed by a </div> and all kinds of strangeness can happen. (The HTML5 parsing algorithm attempts to codify what browsers do for the various possibilities in practice, but relying on error recovery isn't wise.)

          As I said, the self-closing tag syntax with the "/" immediately before the ">" at the end of the tag is only used for elements that have an empty content model, such as <img> and <br>, because they cannot be present in that form in XML. (It's also only necessary to use that form if you're expecting an XML parser to consume the markup, which is not going to happen in a web browser unless you go to a heck of a lot of trouble to make it happen, and even then only in certain browsers. Even sticking an XHTML doctype on there is not going to make it happen. Forget about XHTML.)

          Note that such empty elements have to have a space before the / in order to trick HTML parsers into thinking it's a duff attribute name, but there is no such restriction in XML: an HTML parser seeing <br/> will think it's a tag with the name "br/" and, as that name contains an illegal character, we're back in the land of browsers just making tulip up as they go along; whereas an XML parser will see it as an abbreviated version of <br></br> (which would itself confuse the heck out of an HTML parser if present like that in the markup, with yet more uncertain results).

          If you really want a laugh, try putting <script src="blah.js" /> in the head of the document: the browser will see an unclosed <script> element and treat the rest of the document as a script, and thus not render any of it

          Doctypes are only relevant in that they change the way the browser renders certain things; specifically, certain things are formatted slightly differently and CSS uses a different box model. As a general principle, just put an HTML5 doctype on there and be done with it; that'll work as you need it to all the way back to IE5.5, which is further back than you need .

          If ASP.NET is chucking out <div /> under some circumstances, well, Microsoft. But it's probably not.

          EDIT: On http://validator.w3.org/ go to the "Direct input" tab and select the "fragment" radio button under "More options", and you can put snippets of markup in to see if they're valid, and also experiment to see the difference between valid HTML and valid XHTML, the latter being subject to the well-formedness constraints of XML in addition to the validity constraints of HTML4.01.
          Last edited by NickFitz; 20 February 2014, 00:46.

          Comment


            #6
            Originally posted by NickFitz View Post
            No it isn't. As eek and Bunk say, it's to do with the difference between an element whose content model is "empty" and one that isn't.

            To clear up some terminology: in HTML, a "tag" is a piece of markup that starts with with a "<" then a "/" if it's an end tag or nothing if it's a start tag, then a tag name, then whitespace (which is optional if the tag has no attributes), then zero or more attributes separated by whitespace, then a ">". An "element" is represented by either a start tag and an end tag with some (possibly zero-length) content between them, such as <p>foo</p>, or by a single tag if - and only if - it is incapable of having content, i.e. has an empty content model, such as <br>.

            I'll ignore the id attribute in your example from here on as it isn't relevant to the matter at hand.

            The <tagname /> syntax was introduced as a way of representing HTML tags that had an empty content model in a form that is also well-formed XML, so as to produce XHTML. As hardly anybody has ever produced valid XHTML, browsers have always just treated everything as HTML. Basically, forget XHTML as it's completely irrelevant in this context.

            The problem you have is that when an HTML parser sees <div /> what it actually does is:
            1. < - right, we have the beginning of a tag;
            2. div - it's a start tag (as an end tag would begin with "/") and the tag name is "div";
            3. - a space, so after this we expect either attributes, or the ">" that denotes the end of the tag;
            4. / - an attribute named "/" - but hang on, that's an illegal character in an attribute name, so ignore that;
            5. > - the end of the start tag.


            So, as far as the HTML parser is concerned, it's seen a start "div" tag, and that tag will remain open until either:
            1. A matching end tag "</div>" is reached, closing the div;
            2. A tag (starting or ending) is reached which is not allowed inside this div (e.g. "</body>", in which case take steps to make sense of the ill-formed markup lacking an end tag for the div by closing the div;
            3. The end of the document (or end of the input, if parsing a fragment of markup) is reached, in which case take steps to make sense of the ill-formed markup lacking an end tag for the div by closing the div.


            So your <div /> is never closed by a </div> and all kinds of strangeness can happen. (The HTML5 parsing algorithm attempts to codify what browsers do for the various possibilities in practice, but relying on error recovery isn't wise.)

            As I said, the self-closing tag syntax with the "/" immediately before the ">" at the end of the tag is only used for elements that have an empty content model, such as <img> and <br>, because they cannot be present in that form in XML. (It's also only necessary to use that form if you're expecting an XML parser to consume the markup, which is not going to happen in a web browser unless you go to a heck of a lot of trouble to make it happen, and even then only in certain browsers. Even sticking an XHTML doctype on there is not going to make it happen. Forget about XHTML.)

            Note that such empty elements have to have a space before the / in order to trick HTML parsers into thinking it's a duff attribute name, but there is no such restriction in XML: an HTML parser seeing <br/> will think it's a tag with the name "br/" and, as that name contains an illegal character, we're back in the land of browsers just making tulip up as they go along; whereas an XML parser will see it as an abbreviated version of <br></br> (which would itself confuse the heck out of an HTML parser if present like that in the markup, with yet more uncertain results).

            If you really want a laugh, try putting <script src="blah.js" /> in the head of the document: the browser will see an unclosed <script> element and treat the rest of the document as a script, and thus not render any of it

            Doctypes are only relevant in that they change the way the browser renders certain things; specifically, certain things are formatted slightly differently and CSS uses a different box model. As a general principle, just put an HTML5 doctype on there and be done with it; that'll work as you need it to all the way back to IE5.5, which is further back than you need .

            If ASP.NET is chucking out <div /> under some circumstances, well, Microsoft. But it's probably not.

            EDIT: On The W3C Markup Validation Service go to the "Direct input" tab and select the "fragment" radio button under "More options", and you can put snippets of markup in to see if they're valid, and also experiment to see the difference between valid HTML and valid XHTML, the latter being subject to the well-formedness constraints of XML in addition to the validity constraints of HTML4.01.
            Wow - that's what I call a comprehensive answer.

            Thanks very much - I may have to read it a few times for it all to sink in!

            Comment

            Working...
            X