アニメーションしながら選択肢を絞り込むソート機能
- 2019.05.06
- javascript+css
- javascript, 脱jQuery
カテゴリーの絞込みを、アニメーションを加えて表現しています。
カテゴリを選択すると、一旦全部がアニメーションしながら消え、選択されたカテゴリのものだけがアニメーションしながら表示されます。
実装方法は、カテゴリ選択のボタンに仕込んであるクラス名と、絞り込まれる側の要素と同じクラス名を付けるだけです。
ソースコードと解説
html
<dl> <dt>選択肢:</dt> <dd class="red">赤</dd> <dd class="blue">青</dd> <dd class="green">緑</dd> <dd class="lightblue">水色</dd> <dd class="yellow">黄色</dd> <dd class="purple">紫</dd> <dd class="orange">オレンジ</dd> <dd class="yellowgreen">黄緑</dd> <dd class="pink">ピンク</dd> </dl> <div id="boxes"> <div class="lightblue"></div> <div class="yellow"></div> <div class="purple"></div> <div class="orange"></div> <div class="red"></div> <div class="yellowgreen"></div> <div class="blue"></div> <div class="pink"></div> <div class="green"></div> <div class="yellowgreen"></div> <div class="yellow"></div> <div class="lightblue"></div> <div class="orange"></div> <div class="purple"></div> <div class="yellowgreen"></div> <div class="lightblue"></div> <div class="pink"></div> <div class="yellowgreen"></div> <div class="blue"></div> <div class="purple"></div> <div class="yellow"></div> </div>
css
dt {
font-weight: bold;
display: inline-block;
}
dd {
display: inline-block;
text-decoration: underline;
cursor: pointer;
}
#boxes div {
width: 150px;
height: 150px;
margin: 10px;
display: inline-block;
transition: .5s;
}
#boxes .lightblue { background-color: lightblue;}
#boxes .red { background-color: red;}
#boxes .green { background-color: green;}
#boxes .yellow { background-color: yellow;}
#boxes .yellowgreen { background-color: yellowgreen;}
#boxes .pink { background-color: pink;}
#boxes .orange { background-color: orange;}
#boxes .purple { background-color: purple;}
#boxes .blue { background-color: blue;}
.hidden {
transform: scale(0, 0);
}
アニメーションは css で指定しています。
.hidden {
transform: scale(0, 0);
}
この .hidden を付けたりはずしたりすることで、アニメーションさせています。
#boxes div {
~ 略 ~
transition: .5s;
}
要素には transition を指定しておきます。
「0.5秒かけてアニメーション」という指定になります。
javascript
var btns = document.querySelectorAll('dd'); // 選択肢のボタン
var parent = document.getElementById('boxes'); // 要素を囲う親要素
var box = document.querySelectorAll('#boxes div'); // それぞれのBOX
var selected; // 選択されたクラスを入れるための変数
var selectLi = []; // 選択されたboxを入れておくための配列
var first = true; // 1回目かどうか
for (var i = 0; i < btns.length; i++) {
// 選択肢のクリックがあったら
btns[i].addEventListener('click', function () {
// 1回目の場合の処理
if (first) {
// 選択されたクラス名を取得
selected = this.className;
// 一旦全部をアニメーションで消し
for (var j = 0; j < box.length; j++) {
box[j].classList.add('hidden');
// 選択されたクラスが付いているものだけを selectLi の配列へ
if(box[j].classList.contains(selected)) {
selectLi.push(box[j]);
}
}
// 時間差で処理。消すときのアニメーションを待つため
setTimeout(function () {
// 親要素内の要素をすべて削除
for (var j = 0; j < box.length; j++) {
parent.removeChild(box[j]);
}
// 親要素に選択されたboxを追加
for (var j = 0; j < selectLi.length; j++) {
parent.appendChild(selectLi[j]);
}
// 時間差で処理。アニメーションをさせたいため。
setTimeout(function () {
// hiddenクラスを削除し、アニメーションで表示
for (var j = 0; j < selectLi.length; j++) {
selectLi[j].classList.remove('hidden');
}
},100);
}, 500); // 500ミリ秒後に設定。アニメーションの時間
first = false; // 1回目かどうかのフラグにfalseを代入
}
// 2回目以降の処理
else {
// 選択されたboxをアニメーションで消す。
for (var j = 0; j < selectLi.length; j++) {
selectLi[j].classList.add('hidden');
}
// 選択されたボタンのクラスを取得
selected = this.className;
// 選択された要素を入れるための配列を一旦空にして
selectLi = [];
// 時間差で処理
setTimeout(function () {
// 親要素に一旦もとの要素全部追加して
for (var j = 0; j < box.length; j++) {
parent.appendChild(box[j]);
// 選択されたboxを selectLi 配列へ
if(box[j].classList.contains(selected)) {
selectLi.push(box[j]);
}
}
// 親要素内の要素を全部消し、
for (var j = 0; j < box.length; j++) {
parent.removeChild(box[j]);
}
// 選択された要素だけを親要素に追加
for (var j = 0; j < selectLi.length; j++) {
parent.appendChild(selectLi[j]);
}
// 時間差で処理。アニメーションのため
setTimeout(function () {
for (var j = 0; j < selectLi.length; j++) {
// hiddenクラスを削除して、アニメーションで表示
selectLi[j].classList.remove('hidden');
}
},100);
}, 500);
}
});
}
ソートが1度目かそれ以外かで処理を変えています。
1度ソートしてしまうと、要素の数が減ってしまうので、同じように処理をするとエラーになりました。
var first = true; // 1回目かどうか
この変数で、1度目かどうかを判別します。
まずは1度目の処理。
if (first) {
// 選択されたクラス名を取得
selected = this.className;
// 一旦全部をアニメーションで消し
for (var j = 0; j < box.length; j++) {
box[j].classList.add('hidden');
// 選択されたクラスが付いているものだけを selectLi の配列へ
if(box[j].classList.contains(selected)) {
selectLi.push(box[j]);
}
}
// 時間差で処理。消すときのアニメーションを待つため
setTimeout(function () {
// 親要素内の要素をすべて削除
for (var j = 0; j < box.length; j++) {
parent.removeChild(box[j]);
}
// 親要素に選択されたboxを追加
for (var j = 0; j < selectLi.length; j++) {
parent.appendChild(selectLi[j]);
}
// 時間差で処理。アニメーションをさせたいため。
setTimeout(function () {
// hiddenクラスを削除し、アニメーションで表示
for (var j = 0; j < selectLi.length; j++) {
selectLi[j].classList.remove('hidden');
}
},100);
}, 500); // 500ミリ秒後に設定。アニメーションの時間
first = false; // 1回目かどうかのフラグにfalseを代入
}
流れとしては、
選択されたカテゴリのクラス名を取得
↓
一旦全部を非表示(.hidden をつける。)
↓
選択されたカテゴリのクラス名がついているものだけを別の配列 selectLiへ
↓
要素を削除し、選択されたものを新たに追加
↓
表示(.hidden クラスをとることでアニメーション)
↓
1度目かどうか判別するための変数に、falseを代入
という感じです。
2回目以降は、一旦全部消すのが selectLi となります。
else {
// 選択されたboxをアニメーションで消す。
for (var j = 0; j < selectLi.length; j++) {
selectLi[j].classList.add('hidden');
}
// 選択されたボタンのクラスを取得
selected = this.className;
// 選択された要素を入れるための配列を一旦空にして
selectLi = [];
// 時間差で処理
setTimeout(function () {
// 親要素に一旦もとの要素全部追加して
for (var j = 0; j < box.length; j++) {
parent.appendChild(box[j]);
// 選択されたboxを selectLi 配列へ
if(box[j].classList.contains(selected)) {
selectLi.push(box[j]);
}
}
// 親要素内の要素を全部消し、
for (var j = 0; j < box.length; j++) {
parent.removeChild(box[j]);
}
// 選択された要素だけを親要素に追加
for (var j = 0; j < selectLi.length; j++) {
parent.appendChild(selectLi[j]);
}
// 時間差で処理。アニメーションのため
setTimeout(function () {
for (var j = 0; j < selectLi.length; j++) {
// hiddenクラスを削除して、アニメーションで表示
selectLi[j].classList.remove('hidden');
}
},100);
}, 500);
}
使い方
選択肢を <dd> で指定。
<dd class="red">赤</dd> <dd class="blue">青</dd> <dd class="green">緑</dd> <dd class="lightblue">水色</dd> <dd class="yellow">黄色</dd> <dd class="purple">紫</dd> <dd class="orange">オレンジ</dd> <dd class="yellowgreen">黄緑</dd> <dd class="pink">ピンク</dd>
<dd> でなくても良いですが、その場合は javascript の
var btns = document.querySelectorAll('dd');
を変更してあげて下さい。
選択肢には、それぞれクラスを設定しておきます。
選択肢に設定したクラスを、絞り込まれる側にも指定します。
<div class="lightblue"></div> <div class="yellow"></div> <div class="purple"></div> <div class="orange"></div> <div class="red"></div> <div class="yellowgreen"></div> <div class="blue"></div> <div class="pink"></div> <div class="green"></div> <div class="yellowgreen"></div> <div class="yellow"></div> <div class="lightblue"></div> <div class="orange"></div> <div class="purple"></div> <div class="yellowgreen"></div> <div class="lightblue"></div> <div class="pink"></div> <div class="yellowgreen"></div> <div class="blue"></div> <div class="purple"></div> <div class="yellow"></div>
これも <div> でなくてもOKです。
こちらは javascript の方を変更する必要はありません。
アニメーションのしかたは
.hidden {
transform: scale(0, 0);
}
を変えてあげれば、いろいろできます。
たとえば
.hidden {
transform: scale(0, 1);
}
とか
.hidden {
transform: rotate(180deg);
}
とかもいいですね。
-
前の記事
Bracketsのプラグインでminify化してくれないjavascriptの書き方 2019.04.24
-
次の記事
[javascriptエラー]Expected ‘case’ at column 5, not column 9. 2019.05.06