Front-end developers are often called on to build UI elements that aren’t entirely original. Whether the cause of this phenomenon is a lack of creativity on the part of designers or a particular affinity for certain UI elements among the web-browsing public,
ripping-off drawing inspiration from others’ ideas is common in web design. One of the most prominent sources of such “inspiration” over the past few years is Apple’s Aqua interface. Thanks to this glossy, semi-transparent, gradient-laden design, front-end and Flash developers have spent several years worth of billable hours creating simulated reflections and configuring cover flow components for clients insistent upon having sites that “look more web 2.0″.
One of the most prominent places alphabetical lists are used is in Music and Contacts. In case you aren’t familiar, here’s what it looks like in Music:
The main challenge to overcome is the need to reposition the current section’s header every time the list’s scroll event fires. For instance, while A is the current section, its header must appear to remain fixed at the top of the list until it “collides” with the next section’s header (B). Once A’s header “collides” with B’s header, A’s header becomes fixed to the bottom of its section where it remains until the bottom of the section A exceeds the height of its header. Performing these calculations as the scroll event fires (inconsistently across browsers) is taxing and on users’ machines and results in the header flickering as the list scrolls.
Given this challenge, it is necessary to resort to some sleight of hand. I can create a “fake header” that will remain fixed at the top of the list. This header will remain visible until I need to show headers A and B collide at which time I will hide the fake header, show the animation then update the text in the fake header and unhide it. This alleviates the need to reposition the current section’s header every time the list’s scroll event fires resulting in a better-performing, flicker-free iPhone-style contact list.
This is the perfect use of the under-appreciated definition list element (DL). By using a DL, I can use its child element DT as the header and DD as the list item. There’s only one issue with this approach. I need to keep the elements associated with a certain heading grouped so I can measure groups’ height and position. I could wrap each group in a DIV, but that would be semantically incorrect (DL should only have DT and DD as children), so I’ll use individual DL elements for each group. I wrap my DL elements in a DIV with the ID of “list1” and the class of “listContainer”. This will be the scrolling container and will allow multiple list instances in one page.
When using jQuery, developers often fall into the trap of repeatedly accessing the same DOM element. Without exercising care performance will tank so I want to call methods that access the DOM as infrequently as possible. The obvious way of doing this is by caching elements and wrapped sets. Another way I reduce DOM access method calls is by operating on cached element properties instead of repeatedly retrieving those properties from the DOM. For instance, every time the scroll event fires I need to determine which element is at the top of the list and which element and its previous sibling. To do this efficiently, I reference cached element properties stored in an array instead of accessing the DOM elements’ properties. This drastically increases performance.
Much of the list’s CSS is used to adhere (loosely) to a visual design but some of the styles are instrumental to the functionality. View the source of the sample to see what’s going on with the CSS. It’s pretty simple.