Update – Jan 22, 2009
A new native YUI function is in the works, and does this job better
Recently I was working on optimizing some javascript, and found a slow area that was trying to find the first focusable input in a certain area of the page, and it was taking anywhere from 100 – 500 milliseconds, depending on the size of the DOM tree in that element. After digging into it, I noticed it was using the YAHOO.util.dom.getElementsBy() method, which basically had to walk through the whole DOM tree in this case, testing each node against the boolean method passed in. After calling that, it would then return the first, if any, element that getElementsBy returned. Obviously this was a bad approach, as after you find the first match, there is no need to go further.
I did a little research, and saw that this had come up in a thread on the YUI group. I ended up writing a small method to fill in this functionality I wanted out of YUI, called getFirstDescendantBy(rootEl, method). Below is the code, the function takes a root element, or string id of that element, and then a function to test each element against that has the element being tested as the only input. This function passed in should return a boolean, and is similar to the way the YUI dom function getElementsBy works. Hopefully this will help out some people in similar situations.
function getFirstDescendantBy(rootEl, method) {
var root = typeof rootEl === 'string' ? document.getElementById(rootEl) : rootEl;
var firstDescendant = null;
var children = root.childNodes;
for(var idx in children) {
var child = children[idx];
if(child.nodeType === 1) {
if(method(child)) {
firstDescendant = child;
break;
}else if(child.childNodes.length > 0) {
var recursiveResult = getFirstDescendantBy(child, method);
if(recursiveResult !== null) {
firstDescendant = recursiveResult;
break;
}
}
}
}
return firstDescendant;
}
3 Comments
dfjgifjgijhighjkjhkjhgiuhi
dfjgifjgijhighjkjhkjhgiuhiggf gfngn trfhyfgn hjm
ttdrsea
One Trackback
[...] ago I posted on an additional function for YAHOO.util.Dom called getFirstDescendantBy(). I was following the ticket submitted to the YUI Sourceforge tracker, and saw that it had been [...]