勉強を初めた頃に書いたwebページと合体作業をしていたら、思い通りに表示されず、ぐちゃぐちゃしてしまいました。しょうがないので始めから見直したら、急にコードがすっきりしたのでまとめてみます!
webページ作成していて、情報量が多くなっていき、クリックで開閉するウインドウやアコーディオンなどで説明文を表示したりしたくなりますよね。今回はそんなお話です。
ページの動きとしては
3つの<a>
タグをクリックするとそれぞれに対応した説明文が出て、もう一度押すと消えるようなページです。
実際はPHPも入ってリンク元で表示変えたり、同じ表示を出したりとしてますが、そこまで書くと長くなるので、出したり消したりすることだけにします
さて、先に結局どういうコードになったのかを書いてしまいます。経緯をぐちゃぐちゃするとわからなくなりそうなので。。。
/* aタグのhrefが無くてもポインタが変わるようにする */
a {
cursor : pointer;
}
/* ウインドウ用 デザインは各自設定しましょう。
ここでは最低限記載にしてます。 */
.describe{
position :relative;
}
/* hideで消しておいて、showで表示 */
.hide {
display : none;
}
.show {
display : block;
}
HTML
<!--上3つのaタグをクリックすると下の3つのdivタグ内画像が開く-->
<a onclick="openev(1)">その1</a><br>
<a onclick="openev(2)">その2</a><br>
<a onclick="openev(3)">その3</a><br>
<div id="describe1" class="describe hide">
<button onclick="openev(1)">閉じる</button><br>
<img src="img_1.jpg" alt="図の説明">
</div>
<div id="describe2" class="describe hide">
<button onclick="openev(2)">閉じる</button><br>
<img src="img_2.jpg" alt="図の説明">
</div>
<div id="describe3" class="describe hide">
<button onclick="openev(3)">閉じる</button><br>
<img src="img_3.jpg" alt="図の説明">
</div>
//evalでscript上で文字列でコードを作成し、可変変数にしてます。
//HTML側でopenevの()の中に数字を入れて、その数字でIDと変数を作成する形
function openev(i){
eval("var describe" + i + "= document.getElementById("+"'"+"describe"+i+"'"+");");
eval("describe"+ i + ".classList.toggle('show');");
}
これでaタグ押すと画像と閉じるボタンが一緒に表示され、aタグのリンクでもボタンでも消えるようになりました。さらにリンク元によって表示を変えたいときもこれを応用するとその2だけ表示したりと変えられます。
そして最初どうなっていたのかということですが、、、HTMLとJavascriptがすごいことになってました。
おかしかったところを表記しながら、今回の解説をしていきます。
まず、<a>タグです
<a href="javascript:void(0);" id="open1">その1</a><br>
<a href="javascript:void(0);" id="open2">その2</a><br>
<a href="javascript:void(0);" id="open3">その3</a><br>
こんな感じで、CSSのaは何もせず、javascript:void(0);
でhrefを止め、onclickではなく、idで分けてscript側でクリックイベントを受けたら動かす仕組みでした。そのため、div側の「閉じる」ボタンもid="close1"
のように個別にidつけて表示分すべて作ってました。同じidでは動かなくなるのですべて分けてあったのだと思います。これだと表示箇所1つに2つずつfunctionが必要になってしまいますし、PHPで分岐して、一部を表示させないものをつくったりするとJavaScript側の表示も制御しないと対になったHTMLが存在しないので止まってしまうなど、自由度が制限されてしまいます。
実際に書かれていたJavaScript側は、このように個別にすべて書いてありました。
open1.addEventListener('click', function() { var describe1 = document.getElementById('describe1'); describe1.classList
.toggle('show'); describe1.classList
.toggle('hide'); }); close1.addEventListener('click', function() { var describe1 = document.getElementById('describe1'); describe1.classList.toggle('show'); describe1.classList.toggle('hide'); }); //このあと変数の末尾の数字を変えてコピペで同じものを3組作成
クリックのイベントが発生したら、クラスリストからトグル表示してます。ただ、show
とhide
を併記してトグルにしているつもりのようですが、もともとHTMLにhide
が入っていて、scriptのトグルさんがshow
を入れたり抜いたりしてくれるので、hide
の記載は無くてもOKです。そしてイベントが発生したら個別にfunctionで動かす仕組みなので、イベントが1つならこれでいいですが、複数のときは工夫しないと動かなかったり、コードが長くなったりします。
さあ、これでひとまずスッキリしました。実際のコードはクリック表示が8,9個あったりする箇所があるなど、びっくりするぐらいコードが長く、自分が作ったのに見る気もしないぐらいでした。。。
2022年2月追記
まだ勉強中に書いた記事なので、参考にするにはこのコードでは不完全です。こちらをご覧ください。