ある要素からの親要素を取得するjavascript関数

jQueryのparents()と同等の関数をjQueryレスで実装したいと思い解析して作りました。引数(基点となる要素, 検索する要素)を渡すと、基点となる要素から見て条件にマッチする親要素あるいは親要素群を返す関数です。

/*---------- 親要素を検索する ----------*/
var findParentElement = function(elem, query){
	var result = [];
	var matched = [], cur = elem["parentNode"];
	while ( cur && cur != document ) {
		if ( cur.nodeType == 1 )
			matched.push( cur );
		cur = cur["parentNode"];
	}
	for (var i=0; i<matched.length; i++){
		reg = new RegExp(query,"i");
		if(matched[i].nodeName.match(reg)){
			result = matched.splice(i,1);
			break;
		}
	}
	return result;
};
/*---------- 親要素郡を検索する ----------*/
var findParentElementsMulti = function(elem, query){
	var result = [];
	var matched = [], cur = elem["parentNode"];
	while ( cur && cur != document ) {
		if ( cur.nodeType == 1 )
			matched.push( cur );
		cur = cur["parentNode"];
	}
	for (var i=0; i<matched.length; i++){
		reg = new RegExp(query,"i");
		if(matched[i].nodeName.match(reg)){
			result.push(matched[i]);
		}
	}
	return result;
};

たとえば、以下のようなHTMLがあったときに「親要素を表示」を押すと「div.release-block」のオブジェクトが返ります。「親要素群を表示」を押すと配列で「div.release-block, div.primary-area, div.main-area, div.container」のオブジェクトが返ります。

<div class="container">
  <div class="main-area">
    <div class="primary-area">
      <div class="release-block release-block-parent">
        <h2>本社プレスリリース</h2>
        <dl>
          <dt>2009年11月18日</dt>
          <dd><a href="#" onclick="alert(findParentElement(this,'div'));return(false);">親要素を表示</a></dd>
          <dt>2009年10月29日</dt>
          <dd><a href="#" onclick="alert(findParentElementsMulti(this,'div'));">親要素群を表示</a></dd>
        </dl>
      </div>
      <div class="release-block release-block-group">
        <h2>関連会社プレスリリース</h2>
        <dl>
          <dt>2009年11月18日</dt>
          <dd><a href="#" onclick="alert(findParentElement(this,'div'));return(false);">親要素を表示</a></dd>
          <dt>2009年10月29日</dt>
          <dd><a href="#" onclick="alert(findParentElementsMulti(this,'div'));">親要素群を表示</a></dd>
        </dl>
      </div>
    </div>
  </div>
</div>

サンプル(新しいウィンドウで開きます)

返値を利用すれば条件にマッチする要素でかつ、必要なクラス名だけ抽出することも可能です。同等のファンクションを提供する際、HTMLの構造が違う場合に都度分岐させるのは非常に煩雑で面倒なので、繰り返し適用できるように工夫できます。


3 Responses

  1. ポー より:

    すいません質問させてください。

    サンプルの返値「div.release-block, div.primary-area, div.main-area, div.container」から、
    areaの文字が使われてるクラスだけ抽出するにはどうしたらいいのでしょうか。

    抽出後「.className = “hoge”」などでクラスネームを変更したいのです。

    色々調べてみたんですがどうも上手くいかなくて、お手数ですがよろしくお願い致します。

  2. admin より:

    コメントありがとうございます!

    要素郡から、指定のclass名が含まれている要素のみ抽出する関数を作ってみました。以下をご覧ください。
    親要素郡を取得して「取得した値」と「絞り込む条件のclass名」をこの関数に渡してあげると、
    指定したclass名が含まれる要素のみが返り値として戻ってきます。

    /*---------- 指定のclass名が含まれている要素のみ抽出 ----------*/
    var findByClassName = function(elem, query){
    	var result = [];
    	for (var i=0; i<elem.length; i++){
    		if(elem[i].className.match(query)){
    			result.push(elem[i]);
    		}
    	}
    	return result;
    }

    これを利用したサンプルを以下にアップしました。
    http://tshinobu.com/lab/javascript/find-parent-element_20110601.html

    使えそうでしょうか?ご健闘を祈ります。

  3. ポー より:

    素早いお返事ありがとうございます。

    クラス名を書き換えるサンプル書いていただけるとは感激しております。
    今作ってるコードに組み込み動作しております。

    有用なコードの公開ありがとうございました。

Leave a Reply