[Javascript] 任意エレメントから上位階層を検索するスニペット

2018年5月22日

Javascript Tips テクノロジー プログラミング

WEBページでHTMLのエレメントの下位層を検索する方法はたくさん関数が存在していますが、上位検索を行う関数は基本的にはありません。 parentNodeやparentElementなどで、個別に1階層ごと検索しなければいけません。 そんな時に便利な関数(スニペット)をいくつかパターンで用意したので、ライブラリとしてお使いください。

どんな時に使うの?

ケース1

ページ内のウィジェットなどの中にある要素をクリックした際などに、ウィジェットの基準階層を選択する時。

ケース2

ブログや、掲示板記事で、内容を選択した際に、そのレコードの一番親にあたる部分を選択する時。

ケース3

入力フォームで、任意の入力項目から、その項目が含まれるformタグを検索する時。

ソースコード

class検索

// class名でparentNode以外に上位要素のエレメントを検索する。 var upperLayerClass = function(elm , className){ if(!elm || !className){return;} // 上位1階層から開始 elm = elm.parentNode; // bodyまで検索する。 while(elm.tagName !== "BODY"){ var upperClass = elm.getAttribute("class"); if(upperClass !== null){ var upperClasses = upperClass.split(" "); if(upperClasses.indexOf(className) !== -1){ return elm; } } elm = elm.parentNode; } return null; };

id検索

// ID名でparentNode以外に上位要素のエレメントを検索する。 var upperLayerId = function(elm , id){ if(!elm || !id){return;} // 上位1階層から開始 elm = elm.parentNode; // bodyまで検索する。 while(elm.tagName !== "BODY"){ var upperClass = elm.getAttribute("id"); if(upperClass !== null){ var upperClasses = upperClass.split(" "); if(upperClasses.indexOf(id) !== -1){ return elm; } } elm = elm.parentNode; } return null; };

selector検索

// selectorで上位要素のエレメントを検索する。 var upperSelector = function(elm , selector) { if(!elm || !selector){return;} for (var cur=elm; cur; cur=cur.parentElement) { if (cur.matches(selector)) { break; } } return cur; }

使い方

サンプルHTML

<!DOCTYPE html> <html> <head> <title>upper-search</title> </head> <body> <ol id="test1"> <li class="tests1-1"> <div class="test1-1-1"> <button id="click1">click-1</button> </div> </li> <li class="tests1-2"> <div class="test1-2-1"> <button id="click2">click-2</button> </div> </li> <li class="tests1-3"> <div class="test1-3-1"> <button id="click3">click-3</button> </div> </li> </ol> <ul id="test2"> <li class="tests2-1"> <div class="test2-1-1"> <button id="click4">click-4</button> </div> </li> <li class="tests2-2"> <div class="test2-2-1"> <button id="click5">click-5</button> </div> </li> <li class="tests2-3"> <div class="test2-3-1"> <button id="click6">click-6</button> </div> </li> </ul> </body> </html>

実行テスト

以下の様にイベントをセット document.getElementById("click1").onclick = function(e){ var target = e.currentTarget; console.log(upperLayerClass(target , "test1-1-1")); }

click1をクリックすると

下記の文字列(要素)が返ります。 <div class="test1-1-1"> <button id="click1">click-1</button> </div>

解説と注意点

今回3つのソースを書いたのは、いくつか注意点があり、使用用途に応じて書き換えて使って欲しいためです。 ポイントは、selectorはIEでは"matches"が動かないので、class検索とid検索のようなindexOfを使った書き方で書かなければいけません。 スマートフォンであれば、問題なく使えると思いますが、1点だけ注意すると、ブラウザの古いバージョンでは、いくつかの関数が未対応のものもあるので、下位互換を持たせる書き方に直さないといけない場合もありますが、その辺はサイトポリシーに準拠でいいかと思いますので、「最新のみ」という互換性でいいのであれば、これでOK。 この3つのソースコードは、それぞれ同じフローで行なっております。
1. 対象エレメントの上位を1階層ずつ検索 2. 親階層の属性値をチェック 3. マッチする親要素に到達すれば、その時点で対象の親要素をreturn。

[余談] 子階層検索手段

とりあえず、この記事は親要素検索ですが、子要素の検索は下記のような関数が用意されているので、便利にお使いください。
getElementById getElementsByTagName getElementsByClassName getElementsByName querySelector
他にもあったかなあ??? そういや、こういうデフォルト関数のように、要素のprototypeに入れ込むライブラリにした方がいいかもしれないなあ・・・と思った。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。