5.2. Page RearrangementAdd, Adjust, Change, Delete, DOM, Move, Overlay, Rearrange, Restructure, Remove Figure 5-6. Page Rearrangement5.2.1. Goal StoryDoc is looking at a X-ray image in an online diagnostics system. When the mouse rolls over the body, an "advice box" appears at the bottom of the page with stats to help interpret the image. In case the box gets in the way, he's able to drag it around the page. 5.2.2. ProblemHow can you dynamically restructure the page? 5.2.3. Forces
5.2.4. SolutionAdd, remove, move, and overlay elements by manipulating the DOM. The DOM is a hierarchical structure that defines how elements relate to one another. By adjusting the DOM structure, you can adjust where elements appear on the page. There are also critical CSS styles that affect page structureyou can change these by manipulating DOM elements' style attributes. Note: an online demo (http://ajaxify.com/run/page) illustrates the code concepts throughout this Solution and the code snippets loosely follow from the demo. Adding is normally achieved by introducing a new element as a child of an existing container element, such as body or div. For example, you can create a new div element and add it to a parent div: var message = document.createElement("span"); $("container").appendChild(message); Another way to insert an element is to append to the innerHTML property of the container element: $("container").innerHTML += "<span></span>"; The opposite action is removing. By removing an element from the DOM, you take it off the display: $("container").removeChild($("message")); As a variant of adding and removing, you can keep an element on the page but toggle its visibility using CSS. There are two alternative style properties you can use: the visibility style and the display style. The former will always preserve layout while the latter will cause the element to squeeze in and out when it's shown or hidden. So with no visibility, it's like the element's still there but wearing a coat of invisible paint. This makes layout easy, because everything stays where it is, but it can be ugly to have a big patch of whitespace on the page. With the display style, it's more like the element's really disappeared, so the other elements squeeze in to take the place it had occupied. This makes layout a bit more complex, but is usually better visually. The visibility property alternates between visible and hidden: $("message").style.visibility = "visible"; // Now you see me $("message").style.visibility = "hidden"; // Now you don't ("Invisible paint") display is actually used for more than just showing and hiding an elementit also defines how an element appears when it is visible. Briefly, the main options are block (the default for div elements), inline (the default for span elements), and none (when it's not to be shown). $("message").style.display = "block"; // Now you see me, with block layout $("message").style.display = "inline"; // Now you see me, with inline layout $("message").style.display = "none"; // Now you don't ("Gone away") You can move an element around in a couple of ways. First, you can remove it from one place in the DOM and add it to another: container.removeChild(message); extraContainer.appendChild(message); Second, you can adjust CSS properties. The most direct styles are left, right, top, and bottom, which define the coordinates of the element in question: message.style.top = "150px"; message.style.left = "50px"; But what is the (0,0) point these coordinates are relative to? The precise meaning of these properties is modulated by the positioning element.
Positioning is set with standard CSS styles: message.style.left = "150px"; Finally, you can also overlay elements. An HTML document has "2.5" dimensions, which is to say that it has a limited notion of depth in which elements are able to overlap each other. The critical CSS style here is zIndex, which signifies an element's depth. When two elements occupy the same portion of the page, the element that will appear in front is the one with the higher zIndex. The zIndex is not a real depth, because all that matters is the relative ordering of zIndex values. Against a zIndex of zero, it makes no difference whether an element's zIndex is 1, 10, or 100. The default value is 0, and a zIndex can take on any positive or negative value. message.style.zIndex = -100; // Behind of all elements with default zIndex message.style.zIndex = 100; // In front of all elements with default zIndex 5.2.5. Decisions5.2.5.1. Which positioning style to use?A single application can combine different types of positioning. In most cases, staticthe default positioningsuffices. Nonstatic positioning is most commonly used with more free-floating elements, such as Sprites (Chapter 15) or elements suitable for Drag-And-Drop (Chapter 15). For nonstatic positioning, relative positioning tends to be the most useful, because it allows you to move the element around within a defined container. 5.2.5.2. How will you protect against memory leaks?Continuously adding and removing elements leads to the risk of memory leaks. JavaScript is supposed to perform garbage collection, automatically removing variables that are no longer referenced. However, it's sometimes buggy (notoriously in IE) and, in any event, you have to be sure that elements are really dereferenced when they're no longer used. Some general guidelines are as follows:
5.2.6. Real-World Examples5.2.6.1. TadaListTadaList (http://tadalist.com; a screencast is available at http://www.tadalist.com/theater) allows users to manage TODO items (Figure 5-7). Each TODO item is a phrase, like "Finish homework," and the user can add, remove, and rearrange items. Figure 5-7. TadaList5.2.6.2. Super Maryo WorldSuper Maryo World (http://www.janis.or.jp/users/segabito/JavaScriptMaryo.html) is an outright Ajaxian video game, a clone of the classic Super Mario Bros game implemented with standard Ajax technologies (Figure 5-8). The manipulation of game characters and fixtures illustrates how elements can rapidly be added, removed, and moved around. It's Page Rearrangement, real-time! Figure 5-8. Super Maryo World5.2.6.3. KikoKiko (http://kiko.com) is a direct-manipulation Ajax calendar application. You can add and remove appointments, drag them around to change the time, and stretch them out to increase duration. 5.2.7. Code Example: AjaxPatterns Basic WikiThe Basic Wiki Demo (http://ajaxify.com/run) periodically polls for a fresh list of messages to display. Each time the list is retrieved, it removes all existing messages and adds the new list. The containing element is called messages, and removing all messages involves running a loop across each of its children: while ($("messages").hasChildNodes( )) { $("messages").removeChild($("messages").firstChild); } Each message is used to create a new textarea element (among other things), which is then added to a new div, which in turn is added to the messages container: for (var i=0; i<wikiMessages.length; i++) { var messageArea = document.createElement("textarea"); ... messageDiv = document.createElement("div"); ... messageDiv.appendChild(messageArea); ... $("messages").appendChild(messageDiv); ... } 5.2.8. Related Patterns5.2.8.1. Display MorphingThe Display Morphing pattern (see earlier in this chapter) addresses an element's appearance; this pattern talks about elements' location, visibility, and "height above the page" (zIndex). Together, the two patterns cover all aspects of display manipulation. 5.2.9. MetaphorPage Rearrangement is like adding, removing, and rearranging Post-It notes on a whiteboard. |