Recall that Dojo intentionally does not attempt to replace core
JavaScript functionality; on the contrary, it only augments it where
value can be added so that you can write portable code and incur less
boilerplate. For this reason, you won't see direct replacements for
common DOM operations such as appendChild
, removeChild
, and so on. Still, there are
many utilities that could make DOM manipulation a lot simpler, and
this section is all about how Base helps to make that happen.
Base packs several useful functions that augment and
supplement common DOM functions. The first of these functions,
isDescendant
, shown in Table 2-1, is
self-descriptive. You provide it two arguments (id
values or actual nodes), where the
first argument is the node of interest and the second argument is a
potential ancestor. If the node of interest is in fact a member of
the potential ancestor's DOM tree, the function returns true
.
Table 2-1. Base function for manipulating and handling the DOM
Name | Return type | Comment |
---|---|---|
| Boolean | Returns a Boolean value indicating if a node has a particular ancestor or not and works in nested hierarchies as would be expected. |
The need to make a text on the page unselectable via the
cursor is not uncommon and sometimes can actually enhance usability.
Virtually every browser has a specific way of accomplishing this
task, but no need to worry—you have Dojo. Whenever the need arises,
just use the dojo.setSelectable
function. Here's the self-descriptive API:
dojo.setSelectable(/*String | DomNode*/node, /*Boolean*/selectable)
Tip
Hopefully, it goes without saying that no client-side operation should ever be relied on to protect sensitive content because if something is being viewed in the browser as a native display, it can and will be reverse-engineered.
Base's dojo.style
function
provides a comprehensive means of getting or setting individual
style values for a particular node. Simply provide the node and a
style value in DOM-accessor format (e.g., borderWidth
, not border-width
) to fetch a particular style
value. Providing style value in DOM-accessor format as a third
argument causes the function to act as a setter method instead of a
getter method. For example, dojo.style("foo", "height")
would return
the height of element with an id
of "foo"
, while dojo.style("foo", "height", "100px")
would
set its height to 100 pixels. You can also set multiple style
properties at the same time by using an Object
as the second parameter, like
so:
dojo.style("foo", { height : "100px", width : "100px", border : "1px green" });
While many applications benefit from dojo.style
's ability to manipulate
specific style attributes, there is just as common a need for
adding, removing, toggling, and checking for the existence of a
particular class. Base's suite of functions for manipulating class
can do just that, and they all share a common function signature.
The first parameter is the DOM node of interest, and the second
parameter is a string value indicating the class to manipulate. For
example, adding a class to a node is as simple as dojo.addClass("foo", "someClassName")
.
Note that the class name does not include a leading dot as would
define it in the stylesheet.
Table 2-2 summarizes the various facilities for manipulating the appearance of a node.
Table 2-2. Base functions for style handling
Name | Comment |
---|---|
| Provides a means of getting and setting specific style values on a node. |
| Returns |
| Adds a particular class to a node. |
| Removes a particular class from a node. |
| Adds a class if a node does not have it; removes a class if it does have it. |
Mimicking the same approach as the previous section discussed for styling nodes, Base also provides functions for normalizing the ability to set, get, check for the existence of, and remove attributes. Table 2-3 lists the available functions.
Table 2-3. Base functions for manipulating node attributes
Name | Comment |
---|---|
| Provides a means of getting and setting attributes for a node. |
| Returns |
| Removes an attribute from a node. |
The dojo.attr
function
works just like dojo.style
in
that it can set values for individual attributes or multiple
attributes depending on whether you use the second and third
parameters to specify an attribute and its value, or if you provide
an associative array as the second parameter that contains a
collection of attributes and values. The hasAttr
and removeAttr
functions are self-descriptive
and work just as you would expect.
The built-in methods for manipulating DOM content such as
appendChild
, insertBefore
, and so on can get the job
done, but sometimes it's a lot more convenient to have a uniform
means of placing nodes, and the dojo.place
function, documented in Table 2-4, provides just that. In a nutshell, you
give it three parameters: a node to be placed, a reference node, and
a position that defines the relative relationship. The position
parameter may take on the values "before"
, "after"
, "first"
, and "last"
. The values "before"
and "after"
may be used to for relative
placement in a lateral context, while "first"
and "last"
may be used for absolute placement
in a context that assumes the reference node is the parent of the
node being placed. Position may also be supplied as an Integer
value, which refers to the
absolute position that the node to be placed should have in the
reference node's child nodes.
The CSS box model is a fairly simple topic, but because there are so many inconsistent implementations of it that are available on the Web, things get messy pretty quickly. This short section does little more than scratch the surface, because you really do want to turn to an authoritative reference such as Eric Meyer's CSS: The Definitive Guide (O'Reilly) to really get to the bottom of it all.
Tip
If various inconsistent implementations of the box model aren't enough, there's also the issue of keeping the CSS2 box model and the CSS3 box model straight. You can read about the CSS2 box model in the CSS2 Specification at http://www.w3.org/TR/REC-CSS2/box.html, while the CSS3 working draft is at http://www.w3.org/TR/css3-box/.
The ultra-condensed version of the story, however, is that the box model was designed as a way of providing flexible visual formatting that controls the height and width of content by arranging a series of nested boxes around a page element. Before any more dialogue, take a look at Figure 2-2, which conveys the basic idea.
To summarize the differences between content, margin, padding, and border boxes, review the following relevant blurb from the specification:
The margin, border, and padding can be broken down into left, right, top, and bottom segments (e.g., in the diagram, "LM" for left margin, "RP" for right padding, "TB" for top border, etc.). The perimeter of each of the four areas (content, padding, border, and margin) is called an "edge," so each box has four edges:
1 - content edge or inner edge
The content edge surrounds the element's rendered content.
2 - padding edge
The padding edge surrounds the box padding. If the padding has 0 width, the padding edge is the same as the content edge. The padding edge of a box defines the edges of the containing block established by the box.
3 - border edge
The border edge surrounds the box's border. If the border has 0 width, the border edge is the same as the padding edge.
4 - margin edge or outer edge
The margin edge surrounds the box margin. If the margin has 0 width, the margin edge is the same as the border edge.
As it turns out, two different means of realizing the box model emerged, which is where the divergence begins: the content-box and the border-box. The basic difference between the two approaches can be captured by asking what defines how margins and borders are applied to the content area. With the content-box approach, any area incurred by padding and borders is accounted for outside of the explicit width and height of the content, whereas the border-box approach calls for any padding and borders to be accounted for inside the explicit height and width of the content area. In other words, the content-box approach associates a height/width strictly with only the content, whereas the border-box approach associates a height/width with the border inward.
Tip
Many modern browsers support two modes: standards mode and quirks mode. The content-box approach is associated with standards mode while the border-box approach is associated with quirks mode.
If you're not doing anything very fancy and just want to space out some content, the differences may not be apparent, and you can generally get the same net effect in a number of ways. If you need to achieve a very specific look and feel, however, your decisions may already be made for you—and achieving the same look and feel across browsers is exactly where the (lack of) fun begins.
Dojo attempts to normalize the differences in calculating
various facets of the box model by exposing the dojo.boxModel
attribute, which can take on
a value of "content-box"
or
"margin-box"
as well as the
dojo.marginBox
property and
dojo.contentBox
function, which
can be used to retrieve the coordinates for the boxes. By default,
dojo.boxModel
is set to "content-box"
. In all cases, the box
parameters provided in the following table refer to an Object
containing values for width and
height, along with an upper-left coordinate that defines the box's
area. A sample margin box would look something like { l: 50, t: 200, w: 300: h: 150 }
for a
node offset from its parent 50px to the left, 200px from the top
with a margin width of 300px, and a margin-height of 150px.
To try it out for yourself, copy the following example into a local file and open it up in Firefox:
<body style="margin:3px"> <div id="foo" style="width:4px; height:4px; border:solid 1px;"></div> </body>
Here's some sample output you'd see in Firebug if you copied over the page and experimented with it, and Figure 2-3 shows what it would look like in the browser:
console.log("box model", dojo.boxModel); // content-box console.log("content box", dojo.contentBox("foo")); // l=0 t=0 w=4 h=4 console.log("margin box", dojo.marginBox("foo")); // l=3 t=3 w=6 h=6
Like other functions you've seen in this chapter, calling the functions with only one parameter corresponding to a node returns a value, while calling it with an additional second parameter sets the value for the node. Table 2-5 lists all the properties for working with the box model.
Table 2-5. Box model properties
Name | Return type | Comment |
---|---|---|
| Object | Returns an |
| Object | Returns an |
| Object | Returns margin box
data for a node, including absolute positioning data. In
addition to the |
Tip
Dijit uses the box model facilities extensively to produce portable widgets across browsers.
Get Dojo: The Definitive Guide now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.