Element-swapping method comparison

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Christopher Jeris

    Element-swapping method comparison


    Please help me understand the differences, in semantics, browser
    support and moral preferredness, between the following three methods
    of swapping content in and out of a page via JavaScript. I would also
    appreciate any general criticism you have to offer.

    I don't know yet how to write the degradation-path code for browsers
    that don't support the DOM methods I'm using, so there are some
    commented-out paths below.

    If the content contained form controls, then methods I and II would
    cause hidden controls to be submitted, and method III would cause them
    not to be submitted, correct?


    Here is the page content. The upper area contains three buttons
    that select which text is to be displayed in the lower area. Standard
    HTML wrapper is omitted.

    <!-- control area -->
    <div id="control_are a">
    <button id="button_1" onclick="do_but ton(1);">1</button>
    <button id="button_2" onclick="do_but ton(2);">2</button>
    <button id="button_3" onclick="do_but ton(3);">3</button>
    </div>

    <!-- content area -->
    <div id="content_are a">
    <div class="content" id="content_1"> Content box 1.</div>
    <div class="content" id="content_2"> Content box 2.</div>
    <div class="content" id="content_3"> Content box 3.</div>
    </div>


    Method I. Class swapping. Define two CSS classes, one "hidden"
    and one "non-hidden"; the event-handler changes the className of
    each div.

    <style type="text/css">
    div.content { display: none; }
    div.content_unh idden { display: block; }
    </style>

    <script type="text/javascript">
    var content_boxes = new Array();
    // get the div objects
    if (document.getEl ementById) {
    for (var i = 1; i <= 3; i++) {
    content_boxes[i] = document.getEle mentById("conte nt_" + i);
    }
    } else {
    ; // do something else when we don't have document.getEle mentById
    }

    function do_button(n) {
    for (var i = 1; i <= 3; i++) {
    // if div.className is not provided by the browser's DOM,
    // setting it should be harmless, right?
    content_boxes[i].className = (i == n) ? "content_unhidd en"
    : "content";
    }
    }
    </script>


    Method II. Direct setting of the style.display property. Goodman
    says this is DOM Level 2, not 1, and in particular setting
    style.display to "block" is not supported by IE4, although "none"
    is.

    <script type="text/javascript">
    var content_boxes = new Array();
    // get the div objects
    if (document.getEl ementById) {
    for (var i = 1; i <= 3; i++) {
    content_boxes[i] = document.getEle mentById("conte nt_" + i);
    }
    } else {
    ; // do something else when we don't have document.getEle mentById
    }

    // begin by hiding them all
    if (content_boxes[1].style) {
    for (var i = 1; i <= 3; i++) {
    content_boxes[i].style.display = "none";
    }
    } else {
    ; // do something else when we don't have div.style
    }

    function do_button(n) {
    if (content_boxes[1].style) {
    for (var i = 1; i <= 3; i++) {
    content_boxes[i].style.display = (i == n) ? "block"
    : "none";
    }
    } else {
    ; // do something else when we don't have div.style
    }
    }
    </script>


    Method III. Moving of nodes in and out of the surrounding box by DOM
    methods. I suppose it would be more efficient to wrap _all_ of this
    in a check for DOM support, so that you don't have to check every
    method?

    <script type="text/javascript">
    var bounding_box;
    var content_boxes = new Array();
    // get the div objects
    bounding_box = document.getEle mentById("conte nt_area");
    for (var i = 1; i <= 3; i++) {
    content_boxes[i] = document.getEle mentById("conte nt_" + i);
    }

    // begin by hiding them all
    while (bounding_box.h asChildNodes()) {
    bounding_box.re moveChild(bound ing_box.firstCh ild);
    }

    function do_button(n) {
    // prune out all the elements:
    while (bounding_box.h asChildNodes()) {
    bounding_box.re moveChild(bound ing_box.firstCh ild);
    }
    // then add back in the one we want
    bounding_box.ap pendChild(conte nt_boxes[n]);
    }
    </script>


    Thanks for your time,
    --
    Chris Jeris cjeris@oinvzer. net Apply (1 6 2 4)(3 7) to domain to reply.
  • Yann-Erwan Perio

    #2
    Re: Element-swapping method comparison

    Christopher Jeris wrote:
    [color=blue]
    > Please help me understand the differences, in semantics, browser
    > support and moral preferredness, between the following three methods
    > of swapping content in and out of a page via JavaScript.[/color]

    Changing DOM structure would be theoretically best in swapping content,
    since you really want to reflect a document fragment change; you can of
    course accompany the new fragments with CSS to have a good presentation.

    Now, CSS being more supported across user agents than DOM methods, means
    that you'll see it used more often to achieve the content swapping
    (since the visual rendering would appear to be the same in the end).

    Eventually, most designers will however question the need to have
    content swapping when they can make separate pages:-)
    [color=blue]
    > If the content contained form controls, then methods I and II would
    > cause hidden controls to be submitted, and method III would cause them
    > not to be submitted, correct?[/color]

    I would tend to agree, provided the HTML is well-formed; now I don't
    know why but I wouldn't be surprised to discover that with the buggy
    version of browser X, elements with display set to none are not sent
    along with the form submission:-)
    [color=blue]
    > Method I. Class swapping. Define two CSS classes, one "hidden"
    > and one "non-hidden"; the event-handler changes the className of
    > each div.[/color]
    [color=blue]
    > div.content_unh idden { display: block; }[/color]

    FYI underscores are not permitted in CSS identifiers.
    [color=blue]
    > // if div.className is not provided by the browser's DOM,
    > // setting it should be harmless, right?[/color]

    Yes, but that doesn't mean your fallback mechanism will fire.


    Method I is a good method, although the className property is not
    supported in legacy browsers (Opera 6, Netscape 4, IE4 I think). However
    changing the className can be quite resource-demanding when done frequently.
    [color=blue]
    > Method II. Direct setting of the style.display property. Goodman
    > says this is DOM Level 2, not 1, and in particular setting
    > style.display to "block" is not supported by IE4, although "none"
    > is.[/color]

    A good method too, probably better supported by browsers than classNames
    when you stick to "block" and "none"; certainly faster and the best
    adapted to presentational swapping issue. Note that all display
    properties are however far from being supported anywhere (e.g. table
    layouts).
    [color=blue]
    > Method III. Moving of nodes in and out of the surrounding box by DOM
    > methods. I suppose it would be more efficient to wrap _all_ of this
    > in a check for DOM support, so that you don't have to check every
    > method?[/color]

    Well it depends on your fallback solutions, whether you want to set a
    general fallback solution or many ones... but yes. Feature detection is
    a solid approach which however quickly burdens the code with numerous
    checks. Doing the big part at some entry point can relieve other parts
    of the code.

    Method III is an excellent one when you truly want to swap content; it
    tends to be quite supported since most user agents try now to respect
    the W3C texts. Note that speed might also be an issue if you change
    content in short intervals, since browsers may insert/remove nodes, or
    working on orphaned nodes, at different speed.

    As ever, the real problem you'll have to tackle will have its own
    specificities, which may eventually force strange conceptions. Consider
    filtering/sorting table elements; would it be better to change the
    display or to remove nodes when filtering? What if you need to traverse
    the filtered data frequently? If speed really matters would positioned
    div be faster a table re-arranging?


    Regards,
    Yep.

    Comment

    • Christopher Jeris

      #3
      Re: Element-swapping method comparison

      Yann-Erwan Perio <y-e.perio@em-lyon.com> writes:[color=blue]
      > FYI underscores are not permitted in CSS identifiers.[/color]

      *chris spends a frantic half-hour reading specs*

      Underscores are indeed forbidden by the original CSS 2 spec!
      Fortunately for me, this was apparently changed in a 2001 erratum[1]
      and the CSS 2.1 working draft[2] permits them.

      [1] http://www.w3.org/Style/css2-updates...12-errata.html
      [2] http://www.w3.org/TR/CSS21/

      --
      Chris Jeris cjeris@oinvzer. net Apply (1 6 2 4)(3 7) to domain to reply.

      Comment

      • Yann-Erwan Perio

        #4
        Re: Element-swapping method comparison

        Christopher Jeris wrote:
        [color=blue][color=green]
        >>FYI underscores are not permitted in CSS identifiers.[/color][/color]
        [color=blue]
        > *chris spends a frantic half-hour reading specs*
        >
        > Underscores are indeed forbidden by the original CSS 2 spec!
        > Fortunately for me, this was apparently changed in a 2001 erratum[1]
        > and the CSS 2.1 working draft[2] permits them.[/color]

        *well it's high time for yep to read back some specs*

        Thanks for the correction!

        Comment

        Working...