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; } } }