CSSセレクタのハマりどころ「子要素のみを選択する方法」

2018年10月30日

CSS テクノロジー プログラミング 日記

WEBページでアニメーションを行う場合、javascriptでプログラミングする方法とCSSアニメーションを使用する方法がありますが、いったいどちらがいいのかというと、CSSアニメーションで行う方がいいようです。 その理由は、表示しているPC(端末)に最適なCPU負荷で実行してくれるという点や、表示エンジンがブラウザ標準として対応しているため、非常に高速に表示されるという点が大きいです。 もちろん非常に複雑なアニメーションや、条件分岐などが発生する場合はjavascriptを使って動的アニメーションを作らなければいけない場合がありますが、この場合もCSSとの組み合わせで行う方がクオリティが高いと考えていいでしょう。 そんな便利なCSSですが、最大に武器はセレクタと言われるDOM構造の指定方法が、便利で使いやすく、プログラマーでは無い人でもDOM指定ができる為、WEB制作に関わる人であれば覚えておかないといけない要素になっているようです。

JavascriptのquerySelectorでDOM-rootを指定する方法

Javascriptでの"querySelector"は、CSSのセレクタをそのまま再現できますが、その使い側には以下の2パターンが基本構造としてあります。 // document-rootから検索 document.querySelector(".test"); // id="sample"要素から検索 document.getElementById("sample").querySelector(".test"); document-rootからの選択と、任意の要素から選択するパターンで表したんですが、「document.querySelector("#sample .test");」でいいじゃんというツッコミはおいといて、ここで言いたいのは、この指定では、実はハマリポイントがあるという事です。 <table> <tr> <td> <table><tr><td>hello world !</td></tr></table> </td> </tr> </table> table要素内にtableがある場合や、Bootstrapを使った時などはdivのネスト構造が半端なく深くなる場合に、それぞれの要素にclass名がセットされていて管理されていればいいのですが、必ずしもそうでは無い場合、タグの選択をセレクタで行わなければいけなくなります。 document.querySelector("table td"); 簡単に想像できると思いますが、このように書いてしまうと、tableもtdも2つ存在するため、querySelectorでは、一番最初に検索された要素が返ります。 それならば"querySelectorAll"を使って配列で取得して2番目を取得すればいいかというと、そんな限定的なプログラムは不具合の元になってしまうだけです。 こうした時に、「hello world!」の文字が入ったTD要素を選択したい場合は、このサンプルの場合は以下のように書けます。 document.querySelector("table > tr > td > table > tr > td"); ">"はそれぞれの要素の子要素を選択できるため、有効ですね・・・でもこれは、上位からの構造が明確な場合であって、tr要素がたくさんある表組みのような場合には、一つ一つ指定するわけには行かないはずです。 そこで、上位のtableと下位のtableをそれぞれ別々に指定する方法として、以下のように書くといいようです。 // 1番目のtableを指定 var firstTable = document.querySelector("table:nth-child(1) > tr > td"); var helloWorld = firstTable.querySelector(":scope > table > tr > td"); console.log(td.textContent); >> hello world ! ポイントは":scope"を使う事で指定要素のroot位置を指定できます。 ":scope"は擬似セレクタになるので、他にも使える擬似セレクタを知っておくと、便利にDOM操作が行えるはずです。

querySelectorに関するウンチク

querySelectorは、IE8の時から採用されたjavascriptの関数です。 https://caniuse.com/#search=querySelector 古いブラウザでは利用できないのですが、今現在ではそうした心配をしなくてもいいブラウザ環境になったと言ってもいいかもしれませんね。 この"querySelector"は、実はCSSのセレクタをそのままJavascriptで利用させるために、jQueryの機能として搭載されていたものを、javascript(ES)で採用されたそうです。 この機能により"getElementById"や"getElementsByClassName"などの本来javascriptで使っていたDOM操作方法が全て網羅されてしまったため、エンジニアにとっては非常に整ったプログラミングができるようになりました。 他にもこういう便利関数のスニペットはJavascriptに標準搭載してもらいたいですね。

このブログを検索

ごあいさつ

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