I am writing an internal framework that can have no dependencies (i.e. jQuery, etc.) and am trying to implement my own DOM ready-style functionality. It seems that when a callback in the ready queue (array of callbacks to complete on DOM ready), if an exception is thrown inside that function, execution stops and continues onto the next callback (which is what I want), but Firefox will not report the error (log to the console, trigger onerror, anything). Am I doing something wrong?
I have implemented this using a combination of a pattern by Dean Edwards (http://dean.edwards.name/weblog/2009/03/callbacks-vs-events/) and the jQuery source. I do not wish to implement just like jQuery because if one callback fails, the subsequent callbacks won't execute.
var readyCallbacks = [];
(function () {
var currentHandler,
fireReady,
removeEvents,
loopCallbacks = function () {
for (var i = 0, len = readyCallbacks.length; i < len; i += 1) {
currentHandler = readyCallbacks[i];
fireReady();
}
};
if (document.addEventListener) {
document.addEventListener('readyEvents', function () { currentHandler(); }, false);
fireReady = function () {
var readyEvent = document.createEvent('UIEvents');
readyEvent.initEvent('readyEvents', false, false);
document.dispatchEvent(readyEvent);
};
removeEvents = function () {
window.removeEventListener('load', loopCallbacks, false);
loopCallbacks();
};
document.addEventListener('DOMContentLoaded', removeEvents, false);
window.addEventListener('load', loopCallbacks, false);
} else {
// if < IE 9
document.documentElement.readyEvents = 0;
document.documentElement.attachEvent('onpropertychange', function (e) {
if (e.propertyName === 'readyEvents')
currentHandler();
});
fireReady = function () {
document.documentElement.readyEvents += 1;
};
removeEvents = function () {
window.detachEvent('onload', loopCallbacks);
loopCallbacks();
};
document.attachEvent('onreadystatechange', removeEvents);
window.attachEvent('onload', loopCallbacks);
}
})();
Client.ready = function (callback) {
readyCallbacks.push(callback);
};
Here is my test implementation. The console is written to and the DOM element has been manipulated. In IE error with the UNDEFINED_VARIABLE++;
is shown in the console, but not in Firefox.
<!DOCTYPE html>
<html>
<head>
<script src="Client.js"></script>
<script>
Client.ready(function () {
console.log('logging before error');
UNDEFINED_VARIABLE++; // This does not error in Firefox
console.log('logging after error, not logged in Firefox');
});
Client.ready(function () {
console.log('before DOM access');
document.getElementById('cheese').innerHTML = 'cheese';
console.log('after DOM access');
});
</script>
</head>
<body>
<div id="cheese">test</div>
</body>
</html>