Modifies @Gerrit code to work for anonymous functions, also it simply adds attachEvent functionality back to IE 11 (and polyfill for non ie browsers, although not tested) so the same code can be used. I'm happy I found this page. I was fearful that I would have to do this in VBScript or emulate an older version of IE.
Behavior seems to be the same all the way back to IE5.
Polyfill
if (!window.attachEvent) {
window.attachEvent = Element.prototype.attachEvent = function (ename, efunction) {
if (typeof efunction !== 'function') {
throw new TypeError('Element.prototype.attachEvent - what is trying to be attached is not callable');
}
// We got to append somewhere
var _body = document.getElementsByTagName('body')[0];
// Get IE Version
var msie = (function() {
if (typeof document === "undefined") return false;
var v = 3, div = document.createElement('div'), a = div.all || [];
while (div.innerHTML = '<!--[if gt IE '+(++v)+']><br><![endif]-->', a[0]);
var _detection = v > 4 ? v : /*@cc_on!@*/false;
var _version = _detection === true ? 10 : (!(window.ActiveXObject) && "ActiveXObject" in window) === true ? 11 : _detection;
return _version;
}());
// Fix ActiveX not working
if (msie == 11) {
var _params = efunction.toString().match(/(\(.*\))\ *{/)[1];
var _funcName = efunction.toString().match(/^function\s?([^\s(]*)/)[1];
var _fixAnon = false;
// Allow for anonymous functions
if (_funcName == "") {
_fixAnon = true;
console.warn('Function name not found. Autogenerating');
_funcName = "autogenFunction" + Math.floor(Math.random()*9999).toString()
var _handleFunctionality = "{ var privateFunc = " + efunction.toString() + "; privateFunc.apply(" + _funcName + ", arguments); }";
}
// Only one script for|event can be used. Make sure there isn't one already
var _query = 'script[for=' + this.id + '][event=' + ename + ']';
var _handle = document.querySelectorAll(_query);
var _handleFunc = _funcName + _params + ';';
if (_fixAnon) {
var _newFuncName = _funcName + _params;
var _newFunction = "function " + _newFuncName + " " + _handleFunctionality;
var _newHandle = document.createElement('script');
_newHandle.type = "text/javascript";
_newHandle.appendChild(document.createTextNode(_newFunction));
_body.appendChild(_newHandle);
}
// If script for|event exists, reuse it
if (_handle.length != 0) {
_handleFunc += _handle[0].textContent;
_body.removeChild(_handle[0]);
delete _handle[0];
}
_handle = document.createElement('script');
_handle.setAttribute("for", this.id);
_handle.event = ename;
var _handleText = document.createTextNode(_handleFunc);
_handle.appendChild(document.createTextNode(_handleFunc));
_body.appendChild(_handle);
}
var _event = ename.substr(0,2) == "on" ? ename.substr(2) : ename;
// Polyfill for non ie browsers
if (window.addEventListener) this.addEventListener(_event, efunction, false);
}
}
Example Usage with my ActiveX Object
<script type="text/javascript">
function MyObject_ObjectEvent() {
console.log('I am watching traditionally');
}
var _elem = document.getElementById('MyObject');
_elem.attachEvent('ObjectEvent', function () { console.log('I am watching anonymously') });
_elem.attachEvent('ObjectEvent', MyObject_ObjectEvent);
</script>