Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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!:)

like image 973
Jonny Asmar Avatar asked Oct 09 '12 22:10

Jonny Asmar


1 Answers

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!

like image 159
Jonny Asmar Avatar answered Nov 15 '22 09:11

Jonny Asmar