While modernizing the My Broken Leg page I decided it would be nice to show the large version of the page’s images when users hover over the thumbnails, rather than requiring them to click the thumbnails and be taken to another page. Of course, doing this required my first foray into using JavaScript within a web page. I believe it’s best to learn new languages and tools while trying to accomplish something specific, so this was actually a great opportunity. Not only did I learn a lot about some specific aspects of JavaScript, but I got a good feel for using it in general.
The functionality is written so that a web page uses a single function to create the “active” thumbnail, passing a unique root name of an image and an alternative text string. The function adds a named thumbnail to the page and listens for the appropriate events in order to show and hide the large image as needed. Obviously, the thumbnails and large images need to use the same root file names and be stored in known locations, so the solution isn’t completely generalized.
A more challenging aspect of the project was getting the images to show up in desirable locations. For instance, if the thumbnail appears in the upper left part of the window and there is room to show the full image at the same position, then that is the most desirable location. If the thumbnail is at the right or bottom of the window, then aligning the large image with other edges of the thumbnail would be better. Making these decisions requires knowing the size of the image before it is shown.
A web search turned up many questions about the best way to find an unloaded image’s size and the answers suggested a number of different approaches. I did not have success listening to the image’s “loaded” event, as the image size was usually not updated by the time the event was fired. Instead, I went with the approach of polling the image size during loading to see when it had changed (this happens only at the end of the load). This eventually required creating a new image object each time an large picture was to be shown, rather than changing the source of an existing image object. Using new images made it easy to see when the size changed from zero to non-zero.
Another interesting problem turned up when I decided to let users dismiss the large images not only by moving the cursor out of them but by clicking the mouse. If the cursor was still over the thumbnail, the large image would be shown again immediately! Solving this required keeping a list of all active thumbnail images and checking the mouse position vs all of their bounds whenever a large image is dismissed with a click. If the mouse is over a thumbnail at that time, a different state is entered that disallows showing a large image until the mouse leaves the thumbnail.
I’m pretty happy with the results. They seem fast on my PC, but I will have to check out the behavior on a touch screen device. The ability to click a thumbnail to see the large image was left intact, so that might still work on touchscreens. I will probably use a technique similar to this on some other pages in order to show the description of a page when the user hovers over a link to it.