Adding Find() to NodeList in YUI3

In YUI 3, when searching an array for a value, you have to include the collection module, as the Y.Array.find() function is not built into Y.Array. This is a little annoying, because 9 out of 10 times, I include the collection module, it is just for the Y.Array.find() function. Additionally, because the function isnt built into the core library, it is not used or added to the core features, like NodeList. Yet, I believe having a find() function on NodeList is very useful and this article provides a simply way to augment NodeList.

How to do it…

Y.NodeList.prototype.find = function(fn) {
	var elNode;
	
	if (this.size()) {
		 elNode = Y.Array.find(this._nodes, function(elem) {
			return fn(new Y.Node(elem));
		});
	}
		
	return elNode ? new Y.Node(elNode) : elNode;
};

How it works…

First, this augmentation is dependent on the node and collection modules; so make sure you include them or set this up as a module that requires those two. A NodeList instances has a protected property, _node, that is an array of all the native DOM elements in the NodeList, which can be passed into the Y.Array.find function. This then calls an anonymous function on each element in the _node array, which re-wraps the node with Y.Node, before passing it into the provided evaluation function. If the evaluation function returns true, then the Y.Array.find function stops and the HTML element is return. Otherwise, it will be undefined. The found node then needs to be wrapped by Y.Node again before returning and now you have a find() function for all your NodeList instances.

Theres more

If you can use a selector to find the node you are looking for than the filter() function of NodeList is a better choice. Additinionally, NodeList has a some() that could be forced to behave like a find operation by passing in the output array as the context. However, I believe that adding another simple function is a better approach.