本稿では、複数のグループからなる画像一覧のうち、1つの画像をクリックすると同じグループに属しているすべての画像が新たな要素に複製される仕組みを作成する。見たほうが分かりやすいのでこちらのサンプルを参照してください。
これは画像に限らずどの要素でも通用するので、意外と汎用性はあるかもしれない...
コード
HTMLおよびCSS
<section>
<div class="box">
<img class="box_img" src="./img/腹痛.png">
<img class="box_img" src="./img/不安.png">
</div>
<div class="box">
<img class="box_img" src="./img/授業.png">
<img class="box_img" src="./img/廃棄.png">
</div>
<div id="copy_box" class="box"></div>
</section>
section {
display: block;
position: relative;
width: 90%;
margin: 20px auto;
}
.box {
position: relative;
display: flex;
margin: 20px 0;
background: #e3e3e3;
}
.box .box_img {
height: 150px;
padding: 40px 20px;
margin: 0 auto;
}
section #copy_box {
background: #ecbadd;
}
例えば腹痛.pngの画像をクリックしたら場合、兄弟関係にある要素(今回は不安.png)もすべて複製したい。そのための方法をDOMを使って作成する。なお、複製先は、
<div id="copy_box" class="box"></div>
にする。次の節でjavascriptのコードを解説する。
javascript
先に作成したコードを記載しておく。
var boxImg = document.getElementsByClassName("box_img");
for (var i = 0; i < boxImg.length; i++) {
boxImg[i].addEventListener("click", function() {
const copyBox = document.getElementById("copy_box"); //コピー先の要素をあらかじめ変数にしておく
// もしすでにコピー要素があればそれを消去する。
if ( copyBox.childNodes.length !== 0 ) {
copyBox.innerHTML = "";
return true;
}
const parent = this.parentNode;
const children = parent.children;
for ( var i = 0, len = children.length; i < len; i++ ) {
copyBox.appendChild(children[i].cloneNode(true));
}
})
}
1行目の
var boxImg = document.getElementsByClassName("box_img");
は、クリックの対象になるすべての画像の要素を変数に変換している。
次の行のfor文
for (var i = 0; i < boxImg.length; i++) {
...
すべてのbox_img要素に対してクリックされたら処理をしたいので、DOMを複製している。
boxImg[i].addEventListener("click", function() {
...
特定のbox_img要素がクリックされた際にどのような処理をするかを関数にまとめている。
const parent = this.parentNode;
const children = parent.children;
この2行が今回の本題で、1行目によってクリックした要素の親要素を一度取得し、2行目でその子要素をすべて変数にまとめる処理をしている。.parentは親要素を取得するメソッドで、.childrenは子要素をすべて取得するメソッドです。(もしかしたらいきなり兄弟要素を全て取得できるメソッドがあるかもしれないので用勉強...。)
あとは次の行のfor文でコピー先の要素に突っ込んでいくだけ。
copyBox.appendChild(children[i].cloneNode(true));
に使われている.cloneNode()は要素を複製するためのもので、これを使わないと複製ではなくカット&ペーストになってしまうので注意。.cloneNode()の変数をtrueにするとノードの子も複製され、falseの場合は指定したノードのみが複製されます。
最後に
この技術自体はあまり役に立たない気がするけど、画像をクリックしたらその画像に関連する画像も一気にモーダルに表示されるような機能は割と汎用性が高いと思う。