C
Christopher Jeris
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_area">
<button id="button_1" onclick="do_button(1);">1</button>
<button id="button_2" onclick="do_button(2);">2</button>
<button id="button_3" onclick="do_button(3);">3</button>
</div>
<!-- content area -->
<div id="content_area">
<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_unhidden { display: block; }
</style>
<script type="text/javascript">
var content_boxes = new Array();
// get the div objects
if (document.getElementById) {
for (var i = 1; i <= 3; i++) {
content_boxes = document.getElementById("content_" + i);
}
} else {
; // do something else when we don't have document.getElementById
}
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.className = (i == n) ? "content_unhidden"
: "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.getElementById) {
for (var i = 1; i <= 3; i++) {
content_boxes = document.getElementById("content_" + i);
}
} else {
; // do something else when we don't have document.getElementById
}
// begin by hiding them all
if (content_boxes[1].style) {
for (var i = 1; i <= 3; i++) {
content_boxes.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.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.getElementById("content_area");
for (var i = 1; i <= 3; i++) {
content_boxes = document.getElementById("content_" + i);
}
// begin by hiding them all
while (bounding_box.hasChildNodes()) {
bounding_box.removeChild(bounding_box.firstChild);
}
function do_button(n) {
// prune out all the elements:
while (bounding_box.hasChildNodes()) {
bounding_box.removeChild(bounding_box.firstChild);
}
// then add back in the one we want
bounding_box.appendChild(content_boxes[n]);
}
</script>
Thanks for your time,
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_area">
<button id="button_1" onclick="do_button(1);">1</button>
<button id="button_2" onclick="do_button(2);">2</button>
<button id="button_3" onclick="do_button(3);">3</button>
</div>
<!-- content area -->
<div id="content_area">
<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_unhidden { display: block; }
</style>
<script type="text/javascript">
var content_boxes = new Array();
// get the div objects
if (document.getElementById) {
for (var i = 1; i <= 3; i++) {
content_boxes = document.getElementById("content_" + i);
}
} else {
; // do something else when we don't have document.getElementById
}
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.className = (i == n) ? "content_unhidden"
: "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.getElementById) {
for (var i = 1; i <= 3; i++) {
content_boxes = document.getElementById("content_" + i);
}
} else {
; // do something else when we don't have document.getElementById
}
// begin by hiding them all
if (content_boxes[1].style) {
for (var i = 1; i <= 3; i++) {
content_boxes.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.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.getElementById("content_area");
for (var i = 1; i <= 3; i++) {
content_boxes = document.getElementById("content_" + i);
}
// begin by hiding them all
while (bounding_box.hasChildNodes()) {
bounding_box.removeChild(bounding_box.firstChild);
}
function do_button(n) {
// prune out all the elements:
while (bounding_box.hasChildNodes()) {
bounding_box.removeChild(bounding_box.firstChild);
}
// then add back in the one we want
bounding_box.appendChild(content_boxes[n]);
}
</script>
Thanks for your time,