jQuery 欲しい物を欲しい所に書く

最近とは…と言わずとも、結構な割合で「Simplicityのグローバルメニュー」と言うような検索ワードが集まるようになりました。

まぁ確かに、どのようにするのか、どのようにしたいのかを上手くできない部分ではありますが、普通に簡単にする方法は無きにしも非ずです。

あ、書くのが遅れました。一応、WordpressのテーマSimplicity関連の話ですが、ちょっとSimplicityそのものとは関係無さそうな流れになるのではないかと予想して、タイトルからはSimplicityを外しましたが、基本的な内容から作るとなると大変なのでSimplicityのメニューを流用したりして話します。

例えば、グローバルメニューを変更したいと考えた時、真っ先にcssで何とかならないだろうか?と思われますよね?しかし、Simplicityでcssを変更しているのに上手く動かないとか、設定が反映されないなんてことがよくあります。

で、それらを説明するのにおいて、例えばcssの読み込みがどうとか、セレクタの優先度がどうとかと説明していると大変なので、結論から書きます。

変更できなきゃ、できるようにすればいいじゃん

これが答えであり、今回の主題となる部分なのです。

まず、jQueryありきの説明になるので、個人的にjavascriptは切っておくというような化石時代のセオリーを未だに行っている訪問者は無視する方向になります。そういう人向けに書こうとすれば、PHPファイルをいじくったりしてhtmlが出力される前の段階で仕様を決めておかなければならないのです。
jQueryは、htmlが出力された後にその偉大なる力を発揮しますので、javascriptを切っている訪問者は無視すると言う感じになりますことを予め書いておきます。

できなきゃ、できるようにするを実践するために

まず覚えることが2つあります。

1つは、要素をどのようにして目的の場所に挿入するか、もう1つは目的の要素をどうやって取得するかです。

まず目的の要素を取得する所からはじめましょう。
Simplicityの場合、

メニュー部分の骨組みとしてはこんな感じになっています。navと言うタグは、実質「ここがナビゲーションの場所ですよ」と示しているだけなので、必要なのはその中にある#naviになります。本来のメニュー部分だけで言うなら、更にその中のulとその中身が必要なわけですが、今回は#naviを利用することにします。

ここから2つ方法があります。
1つは、取得した#navi自体を加工する方法と、もう1つは、#naviを複製する方法です。どちらでも構わないのですが、#navi自体を何かしら加工したとしてもセレクタを変えないのであればオリジナルのcssが効いたままになります。なので、ここは複製することを選びます。

複製する方法は、以下の通り。

これで変数naviの中に#naviの中身一式が入る(複製される)ことになります。cloneするだけだと元の#naviの部分は残ってしまいますが、それはちょっと後回しにして、先ほどの「どこに挿入するか」を先に説明したいと思います。

これまでの問題点は「オリジナルのcssが効いてしまう」と言う所にありました。なので、それが効き及ばない部分に複製した#naviを持って行きたい所です。そのために、新たなブロックを作っておき、その中に複製した#naviを入れれば、そのブロックのセレクタの子要素になるので、新たにcssを適用する術を得る事ができるようになります。

ちょっとjQueryをかじった人からすれば、cssが効かない所に複製したものを入れるというのなら、複製せずとも#naviを新たなブロックで囲めばいいじゃないかと言う声も聞こえてきそうです。それも問題ありません。その場合は、

などとしておけば、#naviを.navi-wrapperで囲むことができます。今回は、その方法ではなく、別のブロックを作ると言うことでしたので、その方法を書きますと、例えば、元々ある#naviの後にブロックを入れたい場合、

などと書けます。前に入れたかったら.beforeとか簡単ですね。これでブロックの用意ができました。なので、ここに先ほどの複製した#naviを入れます。

こんな感じです。.navi-wrapperは他にない名前なのでいきなり.クラス名で始めていますが、できればIDなどのそのページに重複しない名称のセレクタから見てどこそこというような指定が望ましいです。また上記では、appendを使っていますがprepend等でも構いません。.navi-wrapperは中身が何もないですから先頭から入れようが、最後尾から入れようが同じだからです。

ここまでを一応、連続して書いておくと、

このようになります。最初の(function($){ … と最後の })(jQuery);は、その括弧の中で$がjQueryとして利用できるようにするためのものです。次の$(function(){ … })は、$(document).ready(function(){ … })と同じ意味で、ドキュメントの準備ができたら実行するというような意味です。

これらは、おまじないとして覚えておくとよいでしょう。

さて、このようにして配置できたら

このような構造ができた感じになります。このままだと、オリジナルのcssが例えば、

このような書き方をしてある場合、今作ったブロック内の#naviもその影響を受けてしまいます。なので、方法としては、IDやclass自体をオリジナルな名称に書き換えると言うのが良いかと思います。例えば.navi-wrapperの中の#navi-inを.n-containerとしたい場合、

こんな感じで付け替えることができます。元々、#navi-inはclassを持っていないので、classにn-containerと付けておき、removeAttrでid自体を消します。
もし.n-containerとあったものを.n-wrapと直したいのであれば、

のような感じになります。このようにして、元々あったものを複製して、新たな箱に入れ、classやidを付け替える事ができれば好きなようにcssを設定できるようになります。それらのセレクタ名は、自分で付けた唯一のものですから、テーマが元々持っているオリジナルのcssのスタイルをどれも継承しません。

こういった理由から、完全に個人のオリジナルスタイルを作れるという感じです。後は元々あった#naviをcssでdisplay: none;としておけば、自分が作成したナビの部分だけが残るという寸法です。リンクなどはオリジナルのものになっているので、スタイルするだけ。

ただし、テーマ側でそのhtmlの構造が変更された場合はjQueryもまた手を入れないといけないようになります。元々のhtmlの構造をどのように変化させたいか、あるいはcssを手きようさせないためには同すればよいかをjQueryで実現するというわけです。

See the Pen fork :: menu, vertical slide 主にWordpress theme Simplicity用 by Hidekichi (@Hidekichi) on CodePen.

これはcodepenにサンプルとして掲載したものですが、ここでも同じような手法を利用しています。javascript欄のコメントでメインの部分辺りを参考までに。

スポンサーリンク

シェアする

フォローする