2011-06-17

Firefox, jQuery, and RegisterStartupScript

I have created a control for the web project I'm working on at work. It's an On/Off slider control, very similar in appearance to the one used by iOS, that uses jQuery to animate the sliding switch on click. Over time, I've added more features and support to it as requirements have come in — its message text is configurable, it can raise its own postback events, and it even works in AJAX postbacks. Someday, I might have to publish the code (maybe when I get rid of its dependence on images and make it size-adjustable as well).

When the control is first rendered, the slider switch is centered halfway between "On" and "Off", and I call Page.ClientScript.RegisterClientScriptBlock that calls that control's "set" function to slide the switch to the correct position. (The control's client click event sets the control's value property and calls this same function to slide the switch back and forth on demand.) It works great on IE, Opera, Chrome… but not Firefox. It would render the first few correctly, but somewhere halfway down the page (depending on how many switches were involved — my particular example page had 10), the slider switches would remain in their centered, "unset" state.

This is getting to be a theme.

I found that, if I added an alert() call before every SetSlider call, then every switch would be set, except the last one. If I reversed the calls so the alert() came second, all the switches would be set.

I was able to solve the problem by wrapping each SetSlider call in a jQuery ready function (i.e., $(function(){ … });). Because the control is self-contained and has no knowledge of other sliders on the page, that's a lot of ready functions; but jQuery seems to handle it without incident. The only other thing I had to deal with was to ensure any startup functions I had to alter the switches' states must come after those SetSlider functions — in my case, moving the code to the page's PreRenderComplete event (because, according to MSDN, the controls' PreRender events, where I registered the SetSlider methods, get called after the page's).

It works, but it still took a couple hours out of my day to find it and then fix it. Thanks again, Firefox.

No comments: