From Ajax Patterns
Tags: Reference DOM Display
In A Blink
Dynamically change the display by modifying the Document Object Model. custom made paper
What does "display" mean in this context?
You're planning the evolution of a page's presentation.nono hair removal
Even though this is a higher-end book on patterns, I don't want the language to get too stale or academic. I think plain speaking is best; so I'd change this to something more along the lines of, "You're converting your current site from static pages to dynamic ones." Or something along those lines, that reads a little more "sitting across the way from the author", and not so much "listening to a lecture or talk from the author." Make sense?
Stuart is trying an online quiz which has a time limit for each question. A countdown box shows the number of seconds remaining. The value dynamically changes each second, and the colour shifts from green to red. As Stuart cannot figure the answer out within the time limit, a "Time's Up" message suddenly appears on the countdown area.
I like that you have a relate-able use-case, or scenario. But I feel when you start putting in people, it feels odd. For some reason, the current story just read really goofy to me; but when I read it like this:
You're creating on online quiz, where each question has a time limit. A countdown box shows the number of seconds remaining to answer the question. The countdown value changes each second, and the color shifts from green to red as time runs out. When the time is up, a "Time's Up" message appears in the countdown area.
-for some reason it feels fine.
How can you dynamically update display elements?
Let's make these active, like our cookbooks, instead of an actual question. So you could say, "You need to dynamically update elements on the page."
- As the user's task and context changes, applications need to present different types of information.
- As information the user is working on changes, information being displayed becomes stale.
- Stale information is a great problem in conventional web applications. Because the information cannot change until it's out of date, you sometimes see disclaimers such as "May Be Out Of Date" or instructions like "Click to Refresh".
- Submitting and redrawing the entire page breaks continuity.
Morph display elements by altering styles and values in the DOM, such as text and colour properties.
This is good, but I'm still not sure it draws enough relation to the Web. I realize it's implied, but I think you're going to actually have to talk more about HTML and the Web, to avoid this feeling more intellectual than it needs to. "display elements" is accurate, but so much more formal than "elements on a Web page".
The DOM makes it straightforward to dynamically change the appearance of page elements. Yes! "page elements" seems so much more focused on the Web. You get a reference to the DOM object for an object on your page, and simply change the appropriate property of that object. The Web browser immediately updates, without any page refresh. This allows you to morph any element on the page - headings, DIVs, images, and even the entire page body. For instance, the AjaxPatterns Assistive Search Demo morphs an image by first getting a reference to the image object according to its id attribute:
categoryImg = document.getElementById(imgId);
Then, the title and style of the image are altered:
categoryImg.title = "Category '" + categoryName + "'" + " probably has results"; categoryImg.style.backgroundColor="yellow";
Note the use here of a particularly important property of HTML objects: style. Because the element's style is exposed, anything that you'd specify in a CSS stylesheet is fair game for changing dynamically. Fonts, backgrounds, borders, and other properties can all be changed after a page has been loaded.
Another common task is changing text on the page. With DOM, this can actually be a surprisingly complex task, especially when markup's involved. Text in the DOM is actually represented by text nodes. Look at the following text, which seems to have some text freely roaming inside a <p> tag:
<p>Oh no! It's <strong>Mr. T</strong>!</p>
What the DOM holds here is actually a paragraph node (p) with three children: a text node, a strong node, and then another text node. Another way to think about it is like this:
<p><textnode>Oh no! It's </textnode><strong>Mr. T</strong><textnode>!</textnode></p>
counterDiv.className = "statusOff"; counterText = counterDiv.firstChild; counterText.nodeValue = counterValue; counterDiv.appendChild(document.createElement("br")); strongText = document.createElement("strong"); strongText.appendChild(document.createTextNode("That's Odd!")); counterDiv.appendChild(strongText);
I felt like this above code was disconnected from the text. You were using the Mr. T example, so I'd stick with that, and show how to create that text. As it is, the className property, as well as the text being created here, come a bit out of the blue, and don't have much context.
Fortunately, there's a workaround, albeit one that is popular though somewhat controversial. The trick involves a property called innerHTML, which lets you change the entire HTML contained within an element. As demonstrated in [/run/demo/displayMorphing/counter/ this innerHTML equivalent of the counter example], you can change text like this:
counterDiv.innerHTML = counterValue; // counterValue is just a number, e.g. "5"
And, because any HTML can be used - not just plain text - the example also includes some markup to produce the exact same message as the DOM manipulation above:
counterSpan.innerHTML = counterValue + "<br> <strong>That's Odd!</strong>";
I'd go back to the Mr. T example again here, as well.
IE also offers an innerText property to change the text in blissful ignorance of the related markup. But it's not portable, and not especially useful; the more portable innerHTML can achieve the same effect, and should be used instead of innerText. Do we have a tagging in place for notes? This above para would be a perfect note in our books.
Needless to say, innerHTML a powerful beast. It makes manipulation code easy to write and easy to understand. It's important to be aware that browser implementations vary, but with modern browsers, it's usually the best option for morphing text.
What Sort of Morphing Should Be Used?
In modern browsers, the DOM is very powerful, so you can change just about anything you can see. Some typical transformations include:
Colour - style.backgroundColor, style.font-color
- Change to a distinguishing colour to highlight an entire image or control, for example to draw the user's attention or indicate that an item has been selected.
- Change to a distinguishing colour to highlight a range of text. This could be combined with a font colour change to indicate that text has been selected.
- Change to a symbolic colour to denote some status change, e.g. "red" for stopped, "green" for running.
- Provide an animation effect by fading or brightening a control. This can draw attention more effectively than a sudden change in the control itself.
- Change colour according to a variable, e.g. the brightness of a blog posting's header varies according to the number of times it's been viewed.
Background Image - style.backgroundImage
- Change the image to indicate the status of an element, e.g. a control might be stopped or started, or source code might be OK, have warnings, or have errorsss.
Border Style - style.borderWidth, style.borderColor, style.borderColor
- Highlight/Select an element to draw attention to it.
- Indicate whether some text is editable or read-only.
Font Style - stylefontSize, style.fontWeight, style.fontStyle
- Change the size, weight, and/or slant of a font to highlight some text.
Inner/Outer HTML- style.innerHTML, style.outerHTML
- Change some text content.
- Change arbitrary HTML, possibly changing the nested HTML of an element as well.mhm
Image Source - src
- Change an image's appearance by modifying the source URL.
Setting Colour and Other Style Properties Based on Dynamic Information
We have mostly discussed styles that are specified as literals in the code. That is, code sets the background colour of an element to yellow. Yellow (represented in code simply by the string "yellow") is a literal value, as are "bold" and "150%". In other words, an element is morphed after the page has loaded, but the the style it changes to has been predetermined by the programmer.
The great thing about DOM morphing, though, is that the style itself can be dynamic. It can vary according to any state information that is available. The online quiz provides a simple example of this behaviour, with the colour shifting according to remaining time (the time is changing as the quiz proceeds). Some websites have been offering a <a href="- http://codecubed.com/map.html">tag soup layout</a>, showing a mix of tags varying font size, with the more popular tags being physically larger. This is another example of dynamic content, as tags are always being reevaluated, and the display updated. In a more realistic context, dynamic styles can be particularly important in decision support systems such as online trading venues or climate monitors, or even e-commerce websites.
Colour is particularly useful in these contexts, because it is essentially a continuous variable; it can be used to represent a wide range of values at a fine degree of precision. Furthermore, it can be used orthogonally to any text on the element. Whereas the text might already be bolded and italicized as part of natural writing style or some othe site convention, the background and font colours can be changed according to a completely different variable (without affecting the formatting text itself).
How do you vary colour dynamically? When you set colour in the DOM, you can either provide a literal value (e.g. "orange") or an RGB value indicating the relative proportion of red, green, and blue. Clearly, it is the RGB format that lets us vary according to continuous variables. You can specify RGB in different ways--#1a5afa is equivalent to rgb(26, 90, 250), which in turn is roughly equivalent to rgb(10%, 35%, 98%)--and the percent value is best for most purposes since it abstracts away low-level details.
So let's say you have a screen element representing three variables--x, y, and z--and you want to change its colour depending on the value of these three values. The simplest solution is to represent x as red, y as green, and z as blue. Then, you set color percentages according to the values of each variable, in proportion possible range the variables can take. If x can vary between 0 and 1000, and it is currently set to 300, then the red percentage is set to 30% (300/1000).
Make the following a note Be sensible about scaling and what the user depicts as continous. If each element represented a country, and one of the variables represented its population, it might make sense to assume some kind of logarithmic scale. So India, with a population of about 1 billion, would be 100%, followed by Mexico, with 100 million, at 90%, followed by Hungary at 10 million at 80%, and so on.
I'm not sure that this section -- from here to my "end" comment -- really belongs here. It's a bit of a rabbit to chase, I think. RGB has a long tradition in programming because it is how screens actually display the details. So it's used in a low-level context and has bubbled all the way up to HTML and is the value provided to the DOM. But in fact, the RGB format has no monopoly on colour specification, and other formats may be more meaningful to humans. In particular, the best-known alternative is HSV - Hue, Saturation, Value (sometimes "Volume" or "Intensity"). What's useful about this format is the breakdown may be more apparent to humans. A user can probably detect countries become brighter as their population increases, even if the hues and saturations all vary in completely different ways. But the user will have a lot more difficulty detecting that the green component increases with population, when the variation in red and blue components is creating a virtually random mosaic of colours. HSV components are simply more natural to humans.
Using HSV or another format is certainly feasible - come up with an algorithm to convert the value into HSV, then just convert it to RGB to get a value which can be given to the DOM. There's various code around to convert to and from RGB (e.g. ).
RGB, HSV, and other prominent formats break colours down to three components, so it's natural to represent "trebles" - three-facet variables - in this way. However, it's certainly possible to represent fewer than three variables, or even more than three variables. One variable can be represented by mapping it to one component and fixing the others. Alternatively, you can come up with some formula as long as the mapping is isomorphic, i.e. that each value of the variable maps to a single colour and vice-versa. You can do similarly for two variables. Isomorphism is an impossibility for four or more variables, unless they are constrained to certain combinations. Use your creativity, and consider dropping a variable or two in order to make the picture clearer. end note
What's the benefit of all this ... is it just about the coolness factor of shifting color? (Not that there's anything wrong with that!) Actually, there's much more to it. If you've explored work by Edward Tufte and others on visualisation and data mining, you'll be aware that presentation can have a mind-bogglingly powerful effect on how data is interpreted, and how much important information can be picked up. Professionals in any discipline tend to become very apt at picking up patterns; in fact, there's good evidence that neural networks form in the brain to support recognition. Some traders, for instance, are prone to use charts and can detect subtle features which are invisible to others. The take-home point for designers is that this pattern recognition is only effective if your system supports it. That's why colours are so effective; you can slap hundreds of numbers on the screen, but those digits don't provide a very good basis for humans to pick up patterns. The number 1 and the number 7 may look quite similar amid a blur of text, but a brightness of 1 will look markedly different to a brightness of 7. It's just the way our brains our wired.
Of course, some websites are likely to induce a severe bout of colour-induced queaziness, as it's easy to go overboard with colours. It's worth noting that choosing colours and themes is virtually a discipline in its own right, involving considerations of graphic arts, neurophysiology, HCI, and electronics. It's no different when colours are varied dynamically; if anything, the right colour scheme can be critical. So you would be advised to consult an expert for any serious design work. The only advice I'll give here is to consider that some users may be colour-blind. That doesn't mean you should design in black-and-white--you should get the most out of colour because it's a wonderful device for most people-but your should be aware of what proportion of users will be affected, the extent to which they will miss out by not having colour, and how you might compensate for that loss of clarity.
The example is a countdown demo based on the story above.
TODO Walkthrough of applying this pattern, with code examples. Before and after states. The example should be related to the initial state and final scenario above.
None for this example.
<TODO Example 1, e.g. "Panning and Zooming (http://maps.google.com)">
<TODO Describe example 1>
<TODO Example 2, e.g. "Panning and Zooming (http://maps.google.com)">
<TODO Describe example 2>
Images Prepared Earlier
Sometimes, images are used instead of changing the style of an element programmatically. For instance, a row of tabs is sometimes created using an image for each selection. Using images in this way has the following advantages:
- Requires less technical effort.
- More portable, since CSS is newer and has greater discrepancies among browser implementations.
- Can be more certain about what the user sees, due to implementation discrepancies.
However, there are some serious downsides:
- Can lead to layout problems if actual image dimensions are used, and suffer from scaling degradation if resized.
- Must anticipate all possible values in advance.
- Increases download time.
- Can only represent discrete data, whereas CSS style properties such as colours and thickness support essentially continuous ranges.
If images are being used to achieve graphics too fancy to be achieved by basic CSS properties, it's worth considering the background-image property, which gives you full control of arbitrary images, combined with the dynamic support of DOM morphing. For example, you can show a tab selection by changing the background images of the previous and current selections.
Just because you can deal with frequent requests doesn't mean you should. If you've taken a modeless approach, these requests will not be showstoppers (literally). But they will nonetheless slow down loading of valuable information, making the application feel less responsive. Use SubmissionThrottling and ExplicitSubmission to cut down on the frequency of server requests.
It was very unclear to me what relevance this had to the page, other than by making a lot of assumptions. I think you need to more clearly relate this to the rest of the pattern.
Display morphing is like using a magic paintbrush and eraser to change the appearance of anything on the page.