The Case of the Version Check Masquerading as a Feature Check


Got an email asking me to check out a forum application that was “behaving weird” on IE11, while behaving correctly on Chrome and Firefox. I’m always interested in having a look at these things, so I got a link and some repro steps and had a look.

The application had a button to add in an image, and this wasn’t doing anything. Having a look, I found that the “button” was actually a span:

<span class="ui-icon ui-icon-plus" data-bind="click:$root.insertImage">

So, it’s JavaScript, so time for some spelunking. It turns out the error in this instance was happening in the following script:

function amaf_insertHTML(html) {
    if (document.getElementById(afeditor).createTextRange) {
        document.getElementById(afeditor).focus(document.getElementById(afeditor).caretPos);
        document.getElementById(afeditor).caretPos = document.selection.createRange().duplicate();
        if (document.getElementById(afeditor).caretPos.text.length > 0) {
            document.getElementById(afeditor).caretPos.text = document.getElementById(afeditor).caretPos.text;
        } else {
            document.getElementById(afeditor).caretPos.text = html;
        };
    } else {
    document.getElementById(afeditor).value += html;
    };
};

Here is why the application appears to be behaving strangely on IE – because it’s running different code than every other browser! That createTextRange check isn’t a feature check – it’s a browser check. IE is the only browser that supports this API, as it isn’t standards based. So, ever other browser is running the single line in the else clause. And IE11, when in IE11 document mode, also works if given the same script as every other browser. However, IE11, when in IE11 document mode, fails if given the “IE specific” script – because this script depends on other deprecated APIs (such as selection, which is replaced by getSelection).

What’s interesting is that the createTextRange isn’t a feature it’s hoping to use – the check is purely used as an “hey, are you IE?” check. It doesn’t actually want to use that API!

So, how could you fix this?

You could put in X-UA-Compatible for IE=11, and then remove the “crusty old IE” code, replacing with this:

function amaf_insertHTML(html) {
    document.getElementById(afeditor).value += html;
};

Alternately, IE does provide you with backwards compatibility, so you could also leave the code alone and throw it into a compatibility mode – in this case, you could use X-UA-Compatible to set IE=10, where the now-deprecated APIs are still supported.

But this is the next stage in the evolution of web content – the compatibility features in IE should only be used to get to a modern browser more quickly, the next initiative should be to get your content up to date. Once you do that, then you can not only unlock modern browsers in general, but really take advantage of them to make amazing experiences. Between now and then, though, we have a lot of poorly written browser checks to eradicate.


Comments (0)

Skip to main content