Selectivizr causes select dropdown to require two clicks to open in IE8 & below
Asked Answered
M

1

6

I recently implemented Selectivizr on an internal company website as we need to support IE7/8. Unfortunately, our site does a lot of dynamic content loading via jQuery/AJAX.

To solve this problem, I overloaded the jQuery ready function to reload Selectivizr after it performs whatever task it was set out to. My code looks like this:

$(function () {
    if ($('body.ie8, body.ie7, body.comp-view8, body.comp-view7').length > 0) {
        (function () {
            var original = jQuery.fn.ready;
            var getSelectivizr;
            jQuery.fn.ready = function () {
                // Execute the original method.
                original.apply(this, arguments);

                clearTimeout(getSelectivizr);
                getSelectivizr = setTimeout(function () {
                    $.getScript(selectivizr);
                }, 50);
            }

        })();
    }
});

Simple enough. However, a teammate recently discovered a bug that seems to be related. In IE8/7 any select dropdown that is dynamically loaded into the page (I'm not sure if static dropdowns are effected as well as none of these pages have them), requires two clicks to open it.

To be more specific, in IE8/7, the first click seems to "focus" on the dropdown, while the second opens it. It Compatibility View, it actually opens for a split-second and then closes. The second click opens it just fine (as long as you remain focused on the dropdown).

I had assumed it might be an issue with what Selectivizr was doing, as it wasn't really designed to work with dynamically loaded content, but after a little bit of debugging, it seems that it's the setTimeout that is causing this strange behavior.

I'm at a complete loss how to fix this without removing my Selectivizr implementation.

It is probably worth noting that the setTimeout is necessary to prevent the browser from attempting to load Selectivizr multiple times if different AJAX calls are made as this can cause serious performance issues within the browser.

Note: this question does not accurately reflect the issue stated in the title, so I updated it to provide better searching! After coming back to this problem a few weeks later, I recognized that my initial debugging had led me down the wrong path. Sorry folks, but I've provided an answer to this which I hope helps!:)

Moldau answered 9/10, 2012 at 22:6 Comment(4)
are you using modernizr as well? does it work you could turn compatability mode off?Feud
Why does Selectivizr need to be reoladed? I thought it was a load-once-there-for-the-life-of-the-page device.Oversleep
Ignore me, I just read a couple of threads in Google Groups, here and hereOversleep
@Feud We are indeed using modernizr. It neither works with compatbility mode on or off. However, the issue seems to be specific to IE7/8, IE9 works fine. @ Beetroot-Beetroot ^_^ Yeh, it unfortunately doesn't apply to any element that's loaded after it because it applies attributes to elements to allow particular selectors to work.Moldau
M
3

So, I've finally had a chance to get back to this bug and it seems the solution was staring me in the face all along, I had just totally missed it due to botching up my initial debugging.

It turns out it was a selectivizr issue all along. Unfortunately, making any sort of change dynamically (JS) to a select box in IE8 and below causes it to be redrawn, which forces it to close (or never open, depending on the version/mode). The way selectivizr works is that it discretely adds a class to elements, such as "slvzr-focus", using JS to mimic the behavior of pseudo-classes; in this case ":focus".

As such, it made sense to simply restrict selectivizr from applying this kind of patch to select boxes on focus. My solution is as follows, though it may not be for everyone (alternatively, you can simply ensure that no ":focus" selectors exist in your CSS, which will cause selectivizr to never fire the event):

1) Find the following line in selectivizr.js:

if (!hasPatch(elm, patch)) {

    if (patch.applyClass && (patch.applyClass === true || patch.applyClass(elm) === true)) {

        cssClasses = toggleClass(cssClasses, patch.className, true);
    }

}

2) Wrap it with the following if statement:

if (!(elm.tagName == 'SELECT' && patch.className == 'slvzr-focus')) {
}

3) The block should look like this when you're done:

if (!(elm.tagName == 'SELECT' && patch.className == 'slvzr-focus')) {
    if (!hasPatch(elm, patch)) {

        if (patch.applyClass && (patch.applyClass === true || patch.applyClass(elm) === true)) {

            cssClasses = toggleClass(cssClasses, patch.className, true);
        }
    }
}

Hope that helps someone out there.

Thanks S/O!

Moldau answered 17/10, 2012 at 12:19 Comment(1)
I have applied the fix and it solved the problem you mentioned in the problem title, hope this fix will not break something else. Thanks!Capreolate

© 2022 - 2024 — McMap. All rights reserved.