Long before Internet Explorer became the browser everyone loves to hate, it was the driving force of innovation on the Internet. Sometimes it’s hard to remember all of the good that Internet Explorer did before Internet Explorer 6 became the scourge of web developers everywhere. Believe it or not, Internet Explorer 4-6 is heavily responsible for web development as we know it today. A number of proprietary features became de facto standards and then official standards with some ending up in the HTML5 specification. It may be hard to believe that Internet Explorer is actually to thank for a lot of the features that we take for granted today, but a quick walk through history shows that it’s true.


If Internet Explorer is a browser that everyone loves to hate, the Document Object Model (DOM) is the API that everyone loves to hate. You can call the DOM overly verbose, ill-suited for JavaScript, and somewhat nonsensical, and you would be correct on all counts. However, the DOM gives developers access to every part of a webpage through JavaScript. There was a time when you could only access certain elements on the page through JavaScript. Internet Explorer 3 and Netscape 3 only allowed programmatic access to form elements, images, and links. Netscape 4 improved the situation by expanding programmatic access to the proprietary <layer> element via document.layers. Internet Explorer 4 improve the situation even further by allowing programmatic access of every element on the page via document.all

In many regards, document.all was the very first version of document.getElementById(). You still used an element’s ID to access it through document.all, such as document.all.myDiv or document.all["myDiv"]. The primary difference was that Internet Explorer used a collection instead of the function, which matched all other access methods at the time such as document.images and document.forms.

Internet Explorer 4 was also the first browser to introduce the ability to get a list of elements by tag name via document.all.tags(). For all intents and purposes, this was the first version of document.getElementsByTagName() and worked the exact same way. If you want to get all <div> elements, you would use document.all.tags("div"). Even in Internet Explorer 9, this method still exists and is just an alias for document.getElementsByTagName().

Internet Explorer 4 also introduced us to perhaps the most popular proprietary DOM extension of all time: innerHTML. It seems that the folks at Microsoft realized what a pain it would be to build up a DOM programmatically and afforded us this shortcut, along with outerHTML. Both of which proved to be so useful, they were standardized in HTML51. The companion APIs dealing with plain text, innerText and outerText, also proved influential enough that DOM Level 3 introduced textContent2, which acts in a similar manner to innerText.

Along the same lines, Internet Explorer 4 introduced insertAdjacentHTML(), yet another way of inserting HTML text into a document. This one took a little longer, but it was also codified in HTML53 and is now widely supported by browsers.


In the beginning, there was no event system for JavaScript. Both Netscape and Microsoft took a stab at it and each came up with different models. Netscape brought us event capturing, the idea that an event is first delivered to the window, then the document, and so on until finally reaching the intended target. Netscape browsers prior to version 6 supported only event capturing.

Microsoft took the opposite approach and came up with event bubbling. They believed that the event should begin at the actual target and then fire on the parents and so on up to the document. Internet Explorer prior to version 9 only supported event bubbling. Although the official DOM events specification evolves to include both event capturing and event bubbling, most web developers use event bubbling exclusively, with event capturing being saved for a few workarounds and tricks buried deep down inside of JavaScript libraries.

In addition to creating event bubbling, Microsoft also created a bunch of additional events that eventually became standardized:

  • contextmenu – fires when you use the secondary mouse button on an element. First appeared in Internet Explorer 5 and later codified as part of HTML54. Now supported in all major desktop browsers.
  • beforeunload – fires before the unload event and allows you to block unloading of the page. Originally introduced in Internet Explorer 4 and now part of HTML54. Also supported in all major desktop browsers.
  • mousewheel – fires when the mouse wheel (or similar device) is used. The first browser to support this event was Internet Explorer 6. Just like the others, it’s now part of HTML54. The only major desktop browser to not support this event is Firefox (which does support an alternative DOMMouseScroll event).
  • mouseenter – a non-bubbling version of mouseover, introduced by Microsoft in Internet Explorer 5 to help combat the troubles with using mouseover. This event became formalized in DOM Level 3 Events5. Also supported in Firefox and Opera, but not in Safari or Chrome (yet?).
  • mouseleave – a non-bubbling version of mouseout to match mouseenter. Introduced in Internet Explorer 5 and also now standardized in DOM Level 3 Events6. Same support level as mouseenter.
  • focusin – a bubbling version of focus to help more easily manage focus on a page. Originally introduced in Internet Explorer 6 and now part of DOM Level 3 Events7. Not currently well supported, though Firefox has a bug opened for its implementation.
  • focusout – a bubbling version of blur to help more easily manage focus on a page. Originally introduced in Internet Explorer 6 and now part of DOM Level 3 Events8. As with focusin, not well supported yet but Firefox is close.