jQueryでDOM探索を実装してみた

任意の対象判定関数を指定できる、前向きあるいは後ろ向きで深さ優先探索する関数を、jQueryで実装してみた。
※例外処理なし
※未単体テスト

使用例

    $('input:text').bind('click', function(e) {
    	var isBackward = e.shiftKey; // シフトを押しながらクリックした場合は後ろ向き探索
    	var n = next($(this), function(node){return node.val() === '';}, isBackward);
    	n.val('次の空はここ!');
    });

作成した機能

/**
 * 指定されたノードを起点として、判定関数が true を返すノードを深さ優先で探索します。
 * @param node 探索の起点となるノード(※jQueryオブジェクト)。このノード自身も探索対象に含まれる
 * @param judgeFunc(node) 引数のノードが探索対象のノードであるかを判定する関数。対象である場合は true を返す
 * @param isBackward true の場合は後ろ向き探索、そうでない場合は前向き探索
 * @param isFromChildren true の場合は、そのノードの子要素を(探索済みであるため)探索しない
 * @return 探索対象が存在した場合はそのノード(※jQueryオブジェクト)、そうでない場合は false
 */
function next (node, judgeFunc, isBackward, isFromChildren) {
	// 探索対象のノードである場合は、これを返す
	if(judgeFunc(node)) {
		return node;
	}
	
	// まだ子要素を探索していない場合は、子要素を探索する
	var children = node.children();
	if(children.length > 0 && !isFromChildren) {
		return next($(children[0]), judgeFunc, isBackward, false);
	}

        // 次の隣接ノードが存在する場合は、それを探索する
	if(isBackward) { // 後ろ向き探索の場合
		var nodeNext = node.prev();
	}
	else { // 前向き探索の場合
		var nodeNext = node.next();
	}
        if(nodeNext.length > 0) {
        	return next($(nodeNext[0]), judgeFunc, isBackward, false);
        }
        else {
        	// 親ノードが存在する場合は、それを探索する
        	var nodeParent= node.parent();
        	if(nodeParent.length > 0) {
        		return next($(nodeParent[0]), judgeFunc, isBackward, true);
        	}
        	// 探索中のノードがルートノードである場合は、探索対象が存在しなかったとして false を返す
        	else {
        		return false;
        	}
        }
}