Skip to content

Instantly share code, notes, and snippets.

@defims
Forked from maettig/LICENSE.txt
Last active June 14, 2016 02:44
Show Gist options
  • Save defims/057999ec4b02da8ba4d635416874a2d7 to your computer and use it in GitHub Desktop.
Save defims/057999ec4b02da8ba4d635416874a2d7 to your computer and use it in GitHub Desktop.
getElementsByClassName in 140byt.es

Several getElementsByClassName() prototype methods in about 140 bytes (more or less). Useful for Internet Explorer <9.0 and (few) other old web browsers that do not support HTML5. Done for 140byt.es.

All "full" versions perfectly match the W3C specification, as far as I know. They support multiple class names in every order and class names that start with or contain dashes or nonascii characters.

The short version (138 bytes) does not support searching for multiple class names and fails when the query string contains any whitespace character.

The "annotated" version is a compromise with a few restrictions (see the comment below). It supports searching for multiple class names and should work in most web browsers.

/**
* This is the long version with support for multiple classes, but it's simplified to make it as
* short as possible (137 bytes). It uses .all (should be supported by most modern web browsers for
* compatibility reasons) instead of .getElementsByTagName('*'). It does not support tab characters
* (neither in the query string nor in the class attributes) and fails if the query string starts
* with whitespace characters.
*/
function(a, b, c, d) //class names and three dummy arguments
{
c = []; //can't build a NodeList, use an Array
for (d in b = //iterate all properties in the NodeList
this. //to be used in a prototype
all //shortcut for getElementsByTagName('*')
)
(b[d].className || '' //for-in also returns "length", skip this
).match( //if the elements class attribute matches
a.replace(/(\S+) */g, //match names in query string, remove spaces
'(?=(^|.* )$1( |$))')) //all names become positive lookaheads
&& c.push(b[d]); //then append to the Array
return c //return the Array
}
// 167 bytes.
function(a,b,c,d){c=[];for(d in b=this.getElementsByTagName('*'))(b[d].className||'').match(a.replace(/\s*(\S+)\s*/g,'(?=(^|.*\\s)$1(\\s|$))'))&&c.push(b[d]);return c}
// 155 bytes. Works in IE9+ only.
function(a){return[].filter.call(this.getElementsByTagName('*'),function(b){return b.className.match(a.replace(/\s*(\S+)\s*/g,'(?=(^|.*\\s)$1(\\s|$))'))})}
// 72 bytes. Works in IE8+ only.
function(a){return this.querySelectorAll(a.replace(/\s+(?=\S)|^/g,'.'))}
export function(a,b,c,d){c=[];for(d in b=this.getElementsByTagName('*'))(b[d].className||'').match('(^|\\s)'+a+'(\\s|$)')&&c.push(b[d]);return c}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 Thiemo Mättig <http://maettig.com/>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "getElementsByClassName",
"description": "Prototype methods for Internet Explorer <9.0 and other old web browsers that do not support HTML5.",
"keywords": [ "class", "dom", "ie", "prototype" ],
"version": "0.1.0"
}
<!DOCTYPE HTML>
<div id="fragment">
<h1 class="findMe-not">Should not match</h1>
<h1 class="test findMe">Should match first</h1>
<p class="findmE">Should not match</p>
<p class="findMe" id="forInFailsInIE">Should match second</p>
<blockquote class="x-findMe">
<p class="findMeNot not">Should not match</p>
<p class="do findMe too">Should be red and third</p>
</blockquote>
</div>
<script type="text/javascript">
function highlight(node)
{
if (!node.getElementsByClassName) return;
var elements = node.getElementsByClassName('findMe');
for (var i = 0; i < elements.length; i++)
{
elements[i].style.background = 'yellow';
elements[i].firstChild.data += ' [' + (i + 1) + ']';
}
elements = node.getElementsByClassName('too findMe');
for (var i = 0; i < elements.length; i++)
{
elements[i].style.background = 'red';
}
}
var fragment = document.getElementById('fragment');
var clone = fragment.cloneNode(true);
fragment.parentNode.appendChild(clone);
highlight(fragment);
clone.constructor.prototype.getElementsByClassName = function(a, b, c, d)
{
c = [];
for (d in b = this.all)
(b[d].className || '').match(a.replace(/(\S+) */g, '(?=(^|.* )$1( |$))')) &&
c.push(b[d]);
return c
}
highlight(clone);
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment