Skip to content

Instantly share code, notes, and snippets.

@mathiasbynens
Created September 14, 2010 22:23
Show Gist options
  • Save mathiasbynens/579895 to your computer and use it in GitHub Desktop.
Save mathiasbynens/579895 to your computer and use it in GitHub Desktop.
Cross-browser-compatible setZeroTimeout
/*! Cross-browser-compatible setZeroTimeout
*
* I took the original setZeroTimeout and made it cross-browser-compatible, using setTimeout(fn, 0) as a fallback in case postMessage is not supported.
* Mathias Bynens <http://mathiasbynens.be/>
* See <http://mathiasbynens.be/notes/settimeout-onload>
*
* Copyright statement below:
*
* See <http://dbaron.org/log/20100309-faster-timeouts>
* By L. David Baron <[email protected]>, 2010-03-07, 2010-03-09
* Released under the following license:
*
* Copyright (c) 2010, The Mozilla Foundation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* - notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* - notice, this list of conditions and the following disclaimer in
* - the documentation and/or other materials provided with the
* - distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
// BEGIN implementation of setZeroTimeout
// Only add setZeroTimeout to the window object, and hide everything else in a closure.
(function() {
var timeouts = [],
messageName = 'zero-timeout-message';
// Like setTimeout, but only takes a function argument. There's
// no time argument (always zero) and no arguments (you have to
// use a closure).
function setZeroTimeoutPostMessage(fn) {
timeouts.push(fn);
window.postMessage(messageName, '*');
}
function setZeroTimeout(fn) {
setTimeout(fn, 0);
}
function handleMessage(event) {
if (event.source == window && event.data == messageName) {
if (event.stopPropagation) {
event.stopPropagation();
}
if (timeouts.length) {
timeouts.shift()();
}
}
}
if (window.postMessage) {
if (window.addEventListener) {
window.addEventListener('message', handleMessage, true);
} else if (window.attachEvent) {
window.attachEvent('onmessage', handleMessage);
}
window.setZeroTimeout = setZeroTimeoutPostMessage;
} else {
window.setZeroTimeout = setZeroTimeout;
}
}());
// END implementation of setZeroTimeout
@mathiasbynens
Copy link
Author

@mathiasbynens
Copy link
Author

In IE7, IE6, Chrome 6 and Safari 5, setZeroTimeout doesn’t delay onload, which is great!

However, based on my demo, it looks like setZeroTimeout delays onload in Firefox 3.6.9, Opera 10.62, IE8, and IE9pre4 :( So it’s not really an alternative to setTimeout(fn, 0) in those browsers.

@mathiasbynens
Copy link
Author

Here’s an alternative by @zcorpan, using MessageChannel: https://www.w3.org/Bugs/Public/show_bug.cgi?id=15007#c16

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment