I recently had the experience of updating a web app designed for IE7 to additionally work in modern browsers (users use predominantly Internet Explorer or Edge). Here I note some changes I needed to make – I couldn’t find any solid documentation on differences in old versions of IE, and much was trial and error.

The application also held some interesting archaeological remnants – it had a check for document.all and document.layers to determine IE or NS, and it used document.main to access a form with a name of “main”. Both work in modern browsers: document.all is supported, document.layers is not, and document.main is the same as document.forms.main, assuming “main” is the name and not only the ID.

ID and Name

In IE, getElementById will get elements with a name of the passed string, in addition to elements with an ID of the passed string.

To fix add an ID equal to the name of the element.

Default type of button element

In IE, the default type of a <button> element is “button”. In modern browsers, the default type is “submit”. This means that in an IE-designed webapp, a button inside a form that does not mean to submit the form (e.g. it opens a pop-up where the user can do something else) may not have a type, but using this functionality in a modern browser will submit the form unexpectedly.

The fix is to add an explicit type="button".

Setting the value of a select

In IE, you can set the value of a HTMLSelectElement list with the statement list.options.value = 'my_val'. In modern browsers this doesn’t do anything.

The fix is to use list.value = 'my_val'.

Security features

After Chromium 69, window.confirm requests not originating on the current page are blocked automatically. This broke a particular workflow used extensively by the app: a button used window.open to open another page with a form in a pop-up. On submit, that page then called opener.document.main.o.value = document.form1.input1.value; opener.call_some_func(); self.close(); where some_func did more things, then called window.confirm for verification.

This is a tricky one to fix:

  • replacing confirm with a different mechanism involves a more extensive rewrite than desired. Some possibilities, like using <dialog>, won’t work in IE.
  • shuffling confirm into the child element wasn’t possible due to the flow of variables.
  • it works in Edge if the developer console is open. This isn’t ideal because it’s a strange requirement and seems like a bug. It did hinder discovering the problem for a long while, though, especially because the error message appears in the developer console, so it’s natural to have it open while debugging!
  • the user can use a different browser: Firefox doesn’t have the feature, and IE always worked. This isn’t ideal because we’d prefer they be able to use their preferred browser.

Microsoft-specific features

IE can use custom JavaScript extensions, such as @cc_on

var xmlhttp;
/*@cc_on
@if (@_jscript_version >= 5)
  try {
    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (E) {
      xmlhttp = false;
    }
  }
@else
xmlhttp = false;
@end @*/

There’s no recourse but to re-implement in JavaScript. In this case it’s trying to produce a XMLHttpRequest.

Race conditions

In IE, functions in a <script> tag may set fields elsewhere on the page – for example, the background color – even if the script precedes the body. Modern browsers are stricter here.

The fix is to move the code into a function called in an onload handler.