Help us understand the problem. What is going on with this article?

parent連打やめろ

More than 5 years have passed since last update.

はじめに

  • jQueryに不慣れな方向けにアンチパターンを紹介する記事です。
  • 親の要素を取得するparentはメソッドチェーンが可能で親の親の要素を取得できます。
  • その感覚で親の親の親の親の…とやってしまいがちですが、今すぐやめましょう。

アンチパターン

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
  </head>

  <body>
    <div data='div1' class='div1'>
      div1
      <div data='div2' class='div2'>
        div2
        <div data='div3' class='div3'>
          div3
          <div data='div4' class='div4'>
            div4
            <div data='div5' class='div5'>
              div5
              <div data='div6' class='div6'>
                <button id='sample'>SAMPLE</button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <script type="text/javascript" src="sample.js"></script>
  </body>
</html>
$(function(){
    $('#sample').on('click', function(){
      var div6 = $(this).parent().attr('data');
      var div5 = $(this).parent().parent().attr('data');
      var div4 = $(this).parent().parent().parent().attr('data');
      var div3 = $(this).parent().parent().parent().parent().attr('data');
      var div2 = $(this).parent().parent().parent().parent().parent().attr('data');
      var div1 = $(this).parent().parent().parent().parent().parent().parent().attr('data');
      console.log(div6);
      console.log(div5);
      console.log(div4);
      console.log(div3);
      console.log(div2);
      console.log(div1);

      alert('please check console log');
    });

});

何故ダメか

  • divが入れ子になって6段ネストしているhtmlがあり、最も親の要素を取得する場合
  • parentを連打するとDOMの構造が変わった時に修正がとても大変
  • 上記の例で言うと例えばdivのネストが1段増えるとか、途中のdivpタグになるとか…
  • あとは単純にコードが読みにくい(このparentは何個上の親を指している?など)

改善コード

$(function(){
    $('#sample').on('click', function(){
      var div6 = $(this).parents('.div6').attr('data');
      var div5 = $(this).parents('.div5').attr('data');
      var div4 = $(this).parents('.div4').attr('data');
      var div3 = $(this).parents('.div3').attr('data');
      var div2 = $(this).parents('.div2').attr('data');
      var div1 = $(this).parents('.div1').attr('data');
      console.log(div6);
      console.log(div5);
      console.log(div4);
      console.log(div3);
      console.log(div2);
      console.log(div1);

      alert('please check console log');
    });

});

解説

  • parentsメソッドはセレクトした要素の親要素を全て取得する。
  • parents(条件)のように条件を指定すると親要素内のその要素を取得する。
  • DOM構造の変化に強い(divのネストが増えても修正が容易)
  • 先程のものと比べてコードが読みやすい。

おまけ

$(function(){
    $('#sample').on('click', function(){
      var div = $(this).closest('div').attr('data');
      console.log(div);

      alert('please check console log');
    });

});
  • closestはその要素の最も近い親要素を1つ取得する。
  • 条件も指定可能なので使い勝手が良い。

おわりに

  • 今回の例では「クラス指定してあんだから普通にクラスでセレクトすればいいだろ!」と思われるかもしれませんが、クリックした要素の親の親の親の…とやりたくなるケースも多々存在します。
  • ループを回して要素を作成していて、その中の1つの要素がクリックされたらその親を辿った要素のテーブルの列をhideにする…などのケースですね(というかそういう例にすれば良かったですね…)
  • とにかく今すぐparent連打はやめましょう。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away