MiniTreeWalker の作りかけ
まだ、修正中ですが、アドバイスお願いします^^;
var Filter_ACCEPT = 1; var Filter_REJECT = 2; var Filter_SKIP = 3; var createMiniTreeWalker = function ( root/* node */, filter/* Function */ ) { if( !root ) return null; if( 'function' !== typeof filter ) filter = function ( node ) { return node; }; // defaultFunction return new MiniTreeWalker( root, filter ); }; var MiniTreeWalker = function ( root, filter ) { //現在のノードの深さ var depth = 0; //現在の基準のノード this.currentNode = root; //初期値? //先祖探し this.parentNode = function ( ) { var n = this.currentNode; var r; while( n = n.parentNode && 0 < depth-- ) { r = filter( n ); if( 1 == r ) return this.currentNode = n; if( 2 == r ) return null; // if( 3 == r ); } return null; }; //最初の子 this.firstChild = function ( ) { var n = this.currentNode.firstChild; var r; while( n ) { r = filter( n ); if( 1 == r ) return ( depth++, this.currentNode = n ); if( 2 == r ) null; // if( 3 == r ); n = n.nextSibling; } return null; }; //最後の子 this.lastChild = function ( ) { var n, r; if( this.currentNode.hasChildNodes() ) { n = this.currentNode.lastChild, depth++; do { r = filter( n ); if( 1 == r ) return ( this.currentNode = n ); if( 2 == r ) return null; // if( 3 == r ); } while( n = n.previousSibling ); } return null; }; //兄貴を探す this.previousSibling = function ( ) { var n = this.currentNode; var r; while( n = n.previousSibling ) { r = filter( n ); if( 1 == r ) return ( this.currentNode = n ); if( 2 == r ) return null; // if( 3 == r ); } return null; }; //舎弟を探す this.nextSibling = function ( ) { var n = this.currentNode; var r; while( n = n.nextSibling ) { r = filter( n ); if( 1 == r ) return ( this.currentNode = n ); if( 2 == r ) return null; // if( 3 == r ); } return null; }; //相対的な前のノード this.previousNode = (function ( get ) { return function ( ) { var o, r; var current = { node: this.currentNode, depth: depth }; while( ( o = get( current ) ) && 0 < o.depth ) { r = filter( o.node ); if( 1 == r ) return ( depth = o.depth, this.currentNode = o.node ); if( 2 == r ) return null; // if( 3 == r ); } return null; }; })(function ( current ) { var n, d = current.depth; if( n = current.node.previousSibling ) { while( n.hasChildNodes( ) ) n = n.lastChild, d++; return { node: n, depth: d }; } return ( n = current.node.parentNode ) ? { node: n, depth: d - 1 }: null; }); //相対的な次のノード this.nextNode = (function ( get ) { return function ( ) { var o, r; var current = { node: this.currentNode, depth: depth }; while( ( o = get( current ) ) && o.node && 0 < o.depth ) { r = filter( o.node ); if( 1 == r ) return ( depth = o.depth, this.currentNode = o.node ); if( 2 == r ) return null; // if( 3 == r ); } return null; }; })(function ( current ) { var cn = current.node, d = current.depth, n; if( n = cn.firstChild ) return { node: n, depth: d + 1 }; do if( n = cn.nextSibling ) return { node: n, depth: d }; while ( d--, cn = cn.parentNode ); return null; }); };