Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
walk and filter DOM nodes by function
function d(
a, // a function to filter the node results (optional)
b, // the ancestor element to walk (optional, defaults to document)
c // placeholder for the result node list
){
b === c && // if b is undefined,
(b=document); // use the document
c = c || []; // intialize the node list if it doesn't exist
if (b) { // if the element exists
if ( // and
!a || a(b) // matches the filter function if one exists,
) c.push(b); // push it to the results.
d(a, b.firstChild, c); // repeat for the first child
d(a, b.nextSibling, c) // repeat for the next sibling
}
return c // return the results
}
function d(a,b,c){b===c&&(b=document);c||(c=[]);if(b){if(!a||a(b))c.push(b);d(a,b.firstChild,c);d(a,b.nextSibling,c)}return c}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 Jed Schmidt <http://jed.is>
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": "walk",
"keywords": ["walk", "filter", "DOM"]
}
@kassens

This comment has been minimized.

Copy link

kassens commented May 22, 2011

c = c || []; could save you 2 byte.

@jed

This comment has been minimized.

Copy link
Owner Author

jed commented May 23, 2011

Good catch, thanks!

@atk

This comment has been minimized.

Copy link

atk commented Jun 9, 2011

Same goes for "b = b || document" instead of "1 in arguments || b = document".

@jed

This comment has been minimized.

Copy link
Owner Author

jed commented Jun 9, 2011

@atk this function is actually sensitive to arity, so this suggestion wouldn't work.

@atk

This comment has been minimized.

Copy link

atk commented Jun 10, 2011

Missed that. But I had another idea: why not a typesafe comparison with the uninitialized placeholder variable, e.g.

function d(a,b,c){b===c&&(b=document);c=c||[];

instead of the much longer

function d(a,b,c){c||(c=[]);1 in arguments||(b=document);

Regards, atk

@jed

This comment has been minimized.

Copy link
Owner Author

jed commented Jun 10, 2011

that's a good call, @atk. changed!

@atk

This comment has been minimized.

Copy link

atk commented Jun 10, 2011

Thanks, @jed

@immaterialh

This comment has been minimized.

Copy link

immaterialh commented Jan 20, 2014

Hiya, I just stumbled across this and think i spotted another shortcut (and just created an account to comment ;-) )
basically using ?: to avoid needing brackets in the ifs

b===c&&(b=document); to b=b===c?document:b; saves a character

if(b){if(!a||a(b))...} to b?(!a||a(b0?...:0)...:0 this saves 3 characters, but needs commas to change to +'s and repeatedly flattens & throws away the arrays, which makes it slower :-/

all together :
function d(a,b,c){b=b===c?document:b;c=c||[];b?(!a||a(b)?c.push(b):0)+d(a,b.firstChild,c)+d(a,b.nextSibling,c):0;return c}

and then using the returned arrays instead of referencing c
ie d(a,...,c)+d(a,...,c)
to d(a,...,d(a,...,c))
saves another 2 & stops the arrays getting flattened :-D
function d(a,b,c){b=b===c?document:b;c=c||[];b?(!a||a(b)?c.push(b):0)+d(a,b.firstChild,d(a,b.nextSibling,c)):0;return c}

and then putting (!a||a(b)?c.push(b):0) in an unused parameter

finally 118 characters
function d(a,b,c){b=b===c?document:b;c=c||[];b?d(a,b.firstChild,d(a,b.nextSibling,c,!a||a(b)?c.push(b):0)):0;return c}

@jpidelatorre

This comment has been minimized.

Copy link

jpidelatorre commented Jun 5, 2018

Moving the assignment for c to the first point where it is needed saves 2 bytes:

// 116 bytes
function d(a,b,c){b=b===c?document:b;b?d(a,b.firstChild,d(a,b.nextSibling,c=c||[],!a||a(b)?c.push(b):0)):0;return c}

Switching the ternaries (except for the first one) for Boolean operations saves another 2:

// 114 bytes
function d(a,b,c){(b=b===c?document:b)&&d(a,b.firstChild,d(a,b.nextSibling,c=c||[],!a||a(b)&&c.push(b)));return c}

Moving the return to the front and bringing the ternary back saves 2 more:

// 112 bytes
function d(a,b,c){return(b=b===c?document:b)?d(a,b.firstChild,d(a,b.nextSibling,c=c||[],!a||a(b)&&c.push(b))):c}

And then, if you were allowed to, you could turn it into a slick arrow function saving 14 more bytes:

// 98 bytes
d=(a,b,c)=>(b=b===c?document:b)?d(a,b.firstChild,d(a,b.nextSibling,c=c||[],!a||a(b)&&c.push(b))):c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.