Skip to content

Commit

Permalink
Replace the <script> solution by an Image() solution
Browse files Browse the repository at this point in the history
Create an <img> element; its error event will be fired asynchronously.

This solution is a non-intrusive alternative to the <script> solution, because it doesn't need to add a new element to the document.
  • Loading branch information
Lcfvs authored and domenic committed Oct 16, 2015
1 parent a54f417 commit e5f53eb
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 16 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ Note that Internet Explorer 8 includes a synchronous version of `postMessage`. W

Unfortunately, `postMessage` has completely different semantics inside web workers, and so cannot be used there. So we turn to [`MessageChannel`][MessageChannel], which has worse browser support, but does work inside a web worker.

### `<script> onreadystatechange`
### `<img> onerror`

For our last trick, we pull something out to make things fast in Internet Explorer versions 6 through 8: namely, creating a `<script>` element and firing our calls in its `onreadystatechange` event. This does execute in a future turn of the event loop, and is also faster than `setTimeout(…, 0)`, so hey, why not?
For our last trick, we pull something out to make things fast in Internet Explorer versions 6 through 8: namely, creating a `<img>` element with an invalid `src`, and firing our calls in its `onerror` event. This does execute in a future turn of the event loop, and is also faster than `setTimeout(…, 0)`, so hey, why not?

## Usage

Expand Down
26 changes: 12 additions & 14 deletions setImmediate.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,20 +118,18 @@
};
}

function installReadyStateChangeImplementation() {
var html = doc.documentElement;
function installImageImplementation() {
setImmediate = function() {
var handle = addFromSetImmediateArguments(arguments);
// Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
// into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
var script = doc.createElement("script");
script.onreadystatechange = function () {
var image = new global.Image();

image.onerror = function() {
runIfPresent(handle);
script.onreadystatechange = null;
html.removeChild(script);
script = null;
};
html.appendChild(script);

// This will always cause an error event to fire.
image.src = "\0";

return handle;
};
}
Expand Down Expand Up @@ -161,12 +159,12 @@
// For web workers, where supported
installMessageChannelImplementation();

} else if (doc && "onreadystatechange" in doc.createElement("script")) {
// For IE 6–8
installReadyStateChangeImplementation();
} else if (doc && global.Image) {
// For IE 6–8, maybe older browsers
installImageImplementation();

} else {
// For older browsers
// Ultimate fallback
installSetTimeoutImplementation();
}

Expand Down

0 comments on commit e5f53eb

Please sign in to comment.