Odd ‘document’ behavior With Prototype.js 1.5 in Safari 2.0.4
Saturday, May 19th, 2007I ran in to an annoying bit of behavior while working on a generic hovering element effect in Safari, using Prototype.js 1.5. Firstly, I’m not well-studied in the general quirks of the onload and unload events, how they work and should work etc, but this issue seems to stand outside that.
The code I’m working on uses the wonderful document.getElementsByClassName to locate the exact element to operate on. Everything was working smoothly, save for the usual and expected cross-browser kinks to be sorted out. Basically I have an element structure like this:
<div class='news-summary'>
<div class='title'>Today's News</div>
<div class='date'>5/18/2004</div>
<div class='summary'>This is a great post...</div>
<div class='admin-toolkit-canvas'>
<a>Edit</a>
</div>
</div>
This represents a simple news preview or summary, possibly one in a list that you might find on a news post index or a side element or portlet. Now if you are logged in as an admin, hovering over the summary should cause a translucent canvas to appear over it, containing easy to access admin functions (like edit). The css class news-summary is a top-level container for summary content, and contained in this is an element of class admin-toolkit-canvas. This element is invisible, and is positioned absolutely within the parent news-summary element. When any child element of the summary element is hovered over, the canvas is rendered. I use document.getElementsByClassName to locate the actual canvas element in various contexts, mainly for showing/hiding it. I had no serious issues until navigating away from the page in the same window, and then using the ‘back’ button in Safari to return to it.
It seemed that the hover events over the summary containers were no longer being handled properly, or more likely that the code I had written to locate the child canvas was breaking.
After some precursory investigation I had assumed this was a side affect of Safari’s handling of the onload event, but further experimenting proved otherwise.
Prototype does some things that some call bad practice, like augmenting core objects and classes provided by the browser environment. One such victim is the global document object, which it equips with the getElementsByClassName method. It works fine… until you return to a page using this method via the back button. So what’s the problem? The augmentations to core objects (not classes), specifically on document made by prototype are apparently reverted. That’s right. No more getElementsByClassName. Why? I’m not sure. This seems to be how WebKit is designed - to blindly (re)initialize the core objects on any page visit.
Is this a bug or a feature? I’m not yet sure. I haven’t done any other tests outside this, nor have I tried the WebKit nightlies. IE and FF seem to work as expected. More to come on this, no doubt. Share some input if you have any!