Last active
February 18, 2021 06:54
-
-
Save brettz9/6093105 to your computer and use it in GitHub Desktop.
(NOTE: This has been since improved to handle negative values at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice#Streamlining_cross-browser_behavior ); Polyfill for "fixing" IE's lack of support (IE < 9) for applying slice on host objects like NamedNodeMap, NodeList, and HTMLCollection (technically, s…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<body id="body" class="abc"><script src="Array.prototype.slice.js"></script><script src="testing-Array.prototype.slice.js"></script> | |
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Polyfill for "fixing" IE's lack of support (IE < 9) for applying slice | |
* on host objects like NamedNodeMap, NodeList, and HTMLCollection | |
* (technically, since host objects are implementation-dependent, | |
* IE hasn't needed to work this way, though I am informed this | |
* will be changing with ES6). Also works on strings, | |
* fixes IE to allow an explicit undefined for the 2nd argument | |
* (as in Firefox), and prevents errors when called on other | |
* DOM objects. | |
* @license MIT, GPL, do whatever you want | |
-* @see https://gist.github.com/brettz9/6093105 | |
*/ | |
(function () { | |
'use strict'; | |
var _slice = Array.prototype.slice; | |
try { | |
_slice.call(document.documentElement); // Can't be used with DOM elements in IE < 9 | |
} | |
catch (e) { // Fails in IE < 9 | |
Array.prototype.slice = function (begin, end) { | |
var i, arrl = this.length, a = []; | |
if (this.charAt) { // Although IE < 9 does not fail when applying Array.prototype.slice | |
// to strings, here we do have to duck-type to avoid failing | |
// with IE < 9's lack of support for string indexes | |
for (i = 0; i < arrl; i++) { | |
a.push(this.charAt(i)); | |
} | |
} | |
else { // This will work for genuine arrays, array-like objects, NamedNodeMap (attributes, entities, notations), NodeList (e.g., getElementsByTagName), HTMLCollection (e.g., childNodes), and will not fail on other DOM objects (as do DOM elements in IE < 9) | |
for (i = 0; i < this.length; i++) { // IE < 9 (at least IE < 9 mode in IE 10) does not work with node.attributes (NamedNodeMap) without a dynamically checked length here | |
a.push(this[i]); | |
} | |
} | |
return _slice.call(a, begin, end || a.length); // IE < 9 gives errors here if end is allowed as undefined (as opposed to just missing) so we default ourselves | |
}; | |
} | |
}()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var body = document.getElementsByTagName('body')[0]; | |
document.write( // Array through normal Array.call (standardized to allow explicit undefined second argument) | |
['a', 'b', 'c', 'd'].slice(0, undefined).splice(1, 2).toString() === 'b,c' | |
); | |
document.write( // Array through Array.prototype.slice.call | |
[].slice.call(['a', 'b', 'c', 'd']).splice(1, 2).toString() === 'b,c' | |
); | |
// Other objects through Array.prototype.slice.call | |
document.write( // String | |
[].slice.call('abcd').toString() === 'a,b,c,d' | |
); | |
document.write( // String | |
[].slice.call('abcd', 1, -1).toString() === 'b,c' | |
); | |
document.write( // NamedNodeMap | |
[].slice.call(body.attributes).toString() === '[object Attr],[object Attr]' | |
); | |
document.write( // NodeList | |
[].slice.call(body.childNodes).toString() === '[object HTMLScriptElement],[object HTMLScriptElement],[object Text]' | |
); | |
document.write( // HTMLCollection | |
[].slice.call(document.getElementsByTagName('HTML')).splice(0, 1).toString() === '[object HTMLHtmlElement]' | |
); | |
document.write( // Array-like object | |
[].slice.call({length: 3, 0: 'a', 1: 'b', 2: 'c'}).toString() === 'a,b,c' | |
); | |
document.write( // Array-like object, slice passed with arguments | |
[].slice.call({length: 3, 0: 'a', 1: 'b', 2: 'c'}, 1, -1).toString() === 'b' | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is broken when end is passed as 0, it is replaced with a.length and returns the entire array.
I changed the code:
This worked for me - there may be a more elegant way to do it.