Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX



Slip Sliding Away: Build an HTML Slider Control : Page 4






Sliders: Get Under the Hood
Libdetect.js is a browser detect script that sets some version flags, much like any browser detect script. Now that browser technology is maturing, you can sometimes rely on the official DOM implementation property to detect the browser version. You can see that done in Listing 2.

The other file, libslider.js, relies on libdetect.js for version flags, and contains only slider-specific functions. I've sweated over portability, so the most obvious bugs are all hammered out. In the future, you can update the library to use Netscape's universal browser detect script. As it is, simple is beautiful.

A core design feature of this slider implementation was the use of images for the visual representation. You can experiment instead with border styles for slots and ticks, as described in the HTML box model, but the bottom line is that their layout is not yet as portable as simply using images, although they might be slightly faster. Even so, the default slot and tick images are very small, and with HTTP pipelining now common, the download overhead for loading the images is truly trivial.

As mentioned above, the file slider.js contains the global array of slider data, which you rename as required. The libslider.js defines the only other global variable, named sliding, which is a Boolean value set to true when the user is mid-slide.

The routine that initially displays the slider is slider_render(). It calls a rendering routine for each slider piece. These are just fancy document.write()'s.

The main code then installs handlers in the Byzantine ways required by the different browsers. In fact, this code is clear enough to use as a general guide for cross-browser events. Note that for Netscape 4.x, the global onMouseMove event gets stomped on. Oh well, version 1.0. In order to get event backwards compatibility right, a pane is used. The pane is a transparent image covering the whole of the slider. It receives all the events. The bonus here is that you can click on the pane "near" the stylus and still get a response.

function slider_render(obj) { var i; var span; with (window.document) { if (old) { write("<BR>No browser support " + for sliders<BR>"); return; } // now write out all the bits slider_render_scale(obj); slider_render_pane(obj); // calculate tabs between ticks if ( obj.tick_tabs == null ) { obj.tick_tabs = (obj.scale_width - obj.tick_width) / (obj.ticks-1.0); } // draw ticks and labels for (i=0; i<obj.ticks; i++){ slider_render_tick(i, obj); slider_render_label(i, obj); } slider_render_stylus_up(obj); slider_render_stylus_down(obj); // Install event handlers if (obj.interactive == true) { if (moz || dom2) { span = getElementById(obj.span_id); span.addEventListener("mousedown", slider_stylus_mousedown, 0); span.addEventListener("mouseup", slider_stylus_mouseup, 0); span.addEventListener("mousemove", slider_stylus_mousemove, 0); } if ( ie4 || ie5 || ie6 ) { span = all(obj.span_id); span.onmousedown = slider_stylus_mousedown; span.onmouseup = slider_stylus_mouseup; span.onmousemove = slider_stylus_mousemove; } if ( nn4 ) { span = layers[obj.span_id]; span.captureEvents (Event.MOUSEDOWN | Event.MOUSEUP | Event.MOUSEMOVE); span.onMouseDown = slider_stylus_mousedown; span.onMouseUp = slider_stylus_mouseup; span.onMouseMove = slider_stylus_mousemove; window.document.onMouseMove = null; } } } }

Listing 3 contains the complete code for the libslider.js file.

The three mouse event handlers in Listing 3 are almost completely different for each browser. Their design is common, though. The two stylus images are exactly z-order stacked. By manipulating their visibility and position in the handlers, you get visual feedback when dragging.

There's also a Terrible Hack. To support multiple sliders per page, handlers need to know which slider they were invoked on. For Netscape 4.x, this is really hard, because it that browser's primitive DOM support. The sample code accomplishes slider identification by appending a local reference the slider's span_id to the URL for the transparent pane. It's a bit like http://pane.gif#slider1 instead of http://pane.gif. Fortunately, Netscape 4.x doesn't care (whew), and we can dig out from the URL the slider name when we need it.

The last few routines calculate which value the slider does or should point to. This saves the user from having to drag to an exact pixel location.

Sliders are a missing piece in the HTML forms toolkit. With modern browsers from both Netscape and Microsoft supporting tabbed interfaces, sliders are one of the few form controls seen in traditional desktop GUI applications that don't also appear on the Web. Well, now they do, and they're a sight more friendly that a big drop-down list of values to pick from. You'll find that the slider is also useful in reports and as a configuration tool. Enjoy.

Nigel McFarlane is a software engineer and technical writer. He spends most of his time in the Telecommunications and MIS problem domains. Reach him by e-mail at nrm@kingtide.com.au.
Comment and Contribute








