jQueryにはslideUp()
,slideDown()
, slideToggle()
といったメソッドがあります。
これらを使用すると、少ないコードで要素をスライドしつつ表示/非表示にできるので、すごく便利ですね。
しかし案件によっては、jQueryを使いたくない場合があるかと思います。
そこで今回の記事では、jQueryのslide系メソッドをJavaScriptで実装する方法を紹介します!
「jQueryを読み込みたくないけど、slide系のメソッドは使用したい」という方は、ぜひ使ってみてください。
【JSとjQueryの比較】slideUp, slideDown, slideToggleのDEMO
以下にJavaScriptとjQueryで実装したDEMOを用意しました。
DEMOには以下の3つの機能を持つボタンを実装しています。
slideUp
…要素をスライドしながら隠すslideDown
…要素をスライドしながら表示するslideToggle
…slideUp
とslideDown
を交互に切り替える
まずは実際の挙動を確認してみてください。
JavaScriptで実装した場合のDEMO
こちらはJavaScriptでslideUp・slideDown・slideToggleを実装したDEMOです。
それぞれのボタンをクリックして、動作を確認してみてください。
slideUp / slideDown / slideToggleのDEMO
jQueryで実装した場合のDEMO
続いてはjQueryのslideUp・slideDown・slideToggleを使用したDEMOです。
jQueryには、これらのメソッドがはじめから用意されていますね。
slideUp / slideDown / slideToggleのDEMO
【比較した結果】JavaScriptでjQueryのslide系メソッドを再現可能!
2つのDEMOを確認していただくとわかると思いますが、JavaScriptでjQueryのslide系メソッドを再現できていますね。
そもそもjQueryはJavaScriptで構成されたライブラリなので、当然素のJavaScriptでも実装することができます!
次で実際のJavaScriptのコードを見ていきましょう。
【コピペ用】slideUp, slideDown, slideToggleの実装JSコード
以下がJavaScriptで実装したslideUp
, slideDown
, slideToggle
の3つの関数のコードです。
// slideUp
const slideUp = (el, duration = 300) => {
el.style.height = el.offsetHeight + "px";
el.offsetHeight;
el.style.transitionProperty = "height, margin, padding";
el.style.transitionDuration = duration + "ms";
el.style.transitionTimingFunction = "ease";
el.style.overflow = "hidden";
el.style.height = 0;
el.style.paddingTop = 0;
el.style.paddingBottom = 0;
el.style.marginTop = 0;
el.style.marginBottom = 0;
setTimeout(() => {
el.style.display = "none";
el.style.removeProperty("height");
el.style.removeProperty("padding-top");
el.style.removeProperty("padding-bottom");
el.style.removeProperty("margin-top");
el.style.removeProperty("margin-bottom");
el.style.removeProperty("overflow");
el.style.removeProperty("transition-duration");
el.style.removeProperty("transition-property");
el.style.removeProperty("transition-timing-function");
}, duration);
};
// slideDown
const slideDown = (el, duration = 300) => {
el.style.removeProperty("display");
let display = window.getComputedStyle(el).display;
if (display === "none") {
display = "block";
}
el.style.display = display;
let height = el.offsetHeight;
el.style.overflow = "hidden";
el.style.height = 0;
el.style.paddingTop = 0;
el.style.paddingBottom = 0;
el.style.marginTop = 0;
el.style.marginBottom = 0;
el.offsetHeight;
el.style.transitionProperty = "height, margin, padding";
el.style.transitionDuration = duration + "ms";
el.style.transitionTimingFunction = "ease";
el.style.height = height + "px";
el.style.removeProperty("padding-top");
el.style.removeProperty("padding-bottom");
el.style.removeProperty("margin-top");
el.style.removeProperty("margin-bottom");
setTimeout(() => {
el.style.removeProperty("height");
el.style.removeProperty("overflow");
el.style.removeProperty("transition-duration");
el.style.removeProperty("transition-property");
el.style.removeProperty("transition-timing-function");
}, duration);
};
// slideToggle
const slideToggle = (el, duration = 300) => {
if (window.getComputedStyle(el).display === "none") {
return slideDown(el, duration);
} else {
return slideUp(el, duration);
}
};
これらを使用する場合は、以下のように記述します。
// スライドさせたい要素を取得
const el = document.querySelector('.element');
// ボタン
const slideUpBtn = document.querySelector(".slide-up-btn");
const slideDownBtn = document.querySelector(".slide-down-btn");
const slideToggleBtn = document.querySelector(".slide-toggle-btn");
// slideUp
slideUpBtn.addEventListener("click", () => {
slideUp(el, 300);
});
// slideDown
slideDownBtn.addEventListener("click", () => {
slideDown(el, 300);
});
// slideToggle
slideToggleBtn.addEventListener("click", () => {
slideToggle(el, 300);
});
slideUp
, slideDown
, slideToggle
の関数には、それぞれ2つの引数を指定できます。
- 第一引数:ターゲット要素
- 第二引数:アニメーションの実行時間(ms)
第一引数には、スライドしながら表示/非表示させるターゲット要素を指定します。
第二引数には、アニメーションの実行時間をミリ秒単位で指定できます。こちらにはデフォルト引数を設定しているので、空白の場合はデフォルト値が適用されるようになっています。
これでJSコードの全体像が確認できました。
次からは、それぞれの関数の解説をしていきます。
【解説】slideUp, slideDown, slideToggleのJSコード解説
ここからは、slideUp
, slideDown
, slideToggle
の実装コードを順番に解説していきます!
コードを理解したいという方は、ぜひ読んでみてください。
slideUpの解説
まずはslideUp
から説明していきます。
slideUp
は、要素をスライドしながら非表示にすることができます。
以下のDEMOでもう一度確認してみてください。
slideUp / slideDown / slideToggleのDEMO
要素が上にスライドしながら隠れるのが確認できたかと思います!
以下でslideUp
の実際のコードをみていきましょう。
// slideUp
const slideUp = (el, duration = 300) => {
el.style.height = el.offsetHeight + "px";
el.offsetHeight;
el.style.transitionProperty = "height, margin, padding";
el.style.transitionDuration = duration + "ms";
el.style.transitionTimingFunction = "ease";
el.style.overflow = "hidden";
el.style.height = 0;
el.style.paddingTop = 0;
el.style.paddingBottom = 0;
el.style.marginTop = 0;
el.style.marginBottom = 0;
setTimeout(() => {
el.style.display = "none";
el.style.removeProperty("height");
el.style.removeProperty("padding-top");
el.style.removeProperty("padding-bottom");
el.style.removeProperty("margin-top");
el.style.removeProperty("margin-bottom");
el.style.removeProperty("overflow");
el.style.removeProperty("transition-duration");
el.style.removeProperty("transition-property");
el.style.removeProperty("transition-timing-function");
}, duration);
};
こちらがslideUp
の全体像ですね。
分解しつつ説明していきます。
/* ① */
el.style.height = el.offsetHeight + "px";
el.offsetHeight;
/* ② */
el.style.transitionProperty = "height, margin, padding";
/* ③ */
el.style.transitionDuration = duration + "ms";
/* ④ */
el.style.transitionTimingFunction = "ease";
/* ⑤ */
el.style.overflow = "hidden";
- ターゲット要素のスタイル属性に
height
を設定。値にはoffsetHeight
で取得したターゲット要素の高さが入る。 transition
を適用するプロパティを指定。ここではheight
,margin
,padding
を徐々に変化させたいので、これらを指定。transition
の実行時間を指定。引数として設定したduration
の値が入る。transition
のタイミング関数を指定。アニメーションの進行具合を調整できる。値にはease-in
,ease-out
,linear
などを指定可能。- 要素がはみ出した場合、その部分を非表示にする
overflow: hidden
を指定。
/* ⑥ */
el.style.height = 0;
el.style.paddingTop = 0;
el.style.paddingBottom = 0;
el.style.marginTop = 0;
el.style.marginBottom = 0;
height
,padding-top
,padding-bottom
,margin-top
,margin-bottom
の値を0にする。
②の時点でheight
, padding
, margin
にtransition
がかかるよう指定しているので、この時点で要素の高さが徐々に小さくなっていき、最終的には0になります。
setTimeout(() => {
/* ⑦ */
el.style.display = "none";
/* ⑧ */
el.style.removeProperty("height");
el.style.removeProperty("padding-top");
el.style.removeProperty("padding-bottom");
el.style.removeProperty("margin-top");
el.style.removeProperty("margin-bottom");
el.style.removeProperty("overflow");
el.style.removeProperty("transition-duration");
el.style.removeProperty("transition-property");
el.style.removeProperty("transition-timing-function");
}, duration);
ここではsetTimeout
を使用して、アニメーション完了後の指定をします。
display: none
を指定して要素を非表示にする。- アニメーション完了後、必要なくなったプロパティを一斉に削除。
以上でslideUp
の解説は終わりです!
slideDownの解説
続いてはslideDown
を解説していきます。
slideDown
は、要素をスライドしながら表示することができる関数ですね。
以下のDEMOで動作確認してみてください。
slideUp / slideDown / slideToggleのDEMO
要素が下にスライドしつつ、徐々に表示されるアニメーションが確認できたかと思います。
以下でslideDown
の実際のコードをみていきましょう。
// slideDown
const slideDown = (el, duration = 300) => {
el.style.removeProperty("display");
let display = window.getComputedStyle(el).display;
if (display === "none") {
display = "block";
}
el.style.display = display;
let height = el.offsetHeight;
el.style.height = 0;
el.style.paddingTop = 0;
el.style.paddingBottom = 0;
el.style.marginTop = 0;
el.style.marginBottom = 0;
el.offsetHeight;
el.style.transitionProperty = "height, margin, padding";
el.style.transitionDuration = duration + "ms";
el.style.transitionTimingFunction = "ease";
el.style.overflow = "hidden";
el.style.height = height + "px";
el.style.removeProperty("padding-top");
el.style.removeProperty("padding-bottom");
el.style.removeProperty("margin-top");
el.style.removeProperty("margin-bottom");
setTimeout(() => {
el.style.removeProperty("height");
el.style.removeProperty("overflow");
el.style.removeProperty("transition-duration");
el.style.removeProperty("transition-property");
el.style.removeProperty("transition-timing-function");
}, duration);
};
slideDown
の実装コードは以上です。
先ほど説明したslideUp
のコードとの共通点が多めですね。
/* ① */
el.style.removeProperty("display");
/* ② */
let display = window.getComputedStyle(el).display;
/* ③ */
if (display === "none") {
display = "block";
}
/* ④ */
el.style.display = display;
- ターゲット要素のstyle属性に
display
が設定されている場合、削除。 - ターゲット要素の
display
プロパティの値を取得し、変数display
に値を格納。 - もしターゲット要素に
display: none
が設定されている場合、block
を指定。 - ②で変数
display
に格納した値を、style属性のdisplay
の値に設定。
ここは一見ややこしく見えますが、
- 要素の
display
の値がnone
の場合…block
を指定する - 要素の
display
の値がnone
以外の場合…CSSで指定されている値をそのまま指定する
という処理を行なっています。
slideDown
は要素を表示する役割を持つので、display
の値はnone
以外にする必要がありますよね。
この記述をすることでblock
, inline-block
, flex
など、ターゲットにどのプロパティが設定されていても柔軟に対応することができます。
/* ⑤ */
let height = el.offsetHeight;
/* ⑥ */
el.style.height = 0;
el.style.paddingTop = 0;
el.style.paddingBottom = 0;
el.style.marginTop = 0;
el.style.marginBottom = 0;
- 変数
height
にターゲット要素の高さを格納。 height
, 上下padding
, 上下margin
を0
にしてstyle属性に設定。
/* ⑦ */
el.style.transitionProperty = "height, margin, padding";
el.style.transitionDuration = duration + "ms";
el.style.transitionTimingFunction = "ease";
/* ⑧ */
el.style.overflow = "hidden";
transition-property
,transition-duration
,transition-timing-function
をそれぞれ設定。- 親要素からはみ出す部分を非表示にする
overflow: hidden
を指定。
/* ⑨ */
el.style.height = height + "px";
/* ⑩ */
el.style.removeProperty("padding-top");
el.style.removeProperty("padding-bottom");
el.style.removeProperty("margin-top");
el.style.removeProperty("margin-bottom");
- ⑤で取得した高さをstyle属性の
height
に設定。 padding
,margin
の上下の値をstyle属性から取り除く。
ステップ⑥で、height
, 上下padding
, 上下margin
の値を0にしましたね。
ステップ⑨⑩では、0にしたそれぞれの値をもとの数値に戻していきます。
まず⑤で取得した要素の高さを、style属性のheight
に指定します。
これで要素が持つ本来の高さを指定できました。
次に、0を指定していた上下padding
, margin
をstyle属性から取り除きます。
これでCSSに指定したpadding
とmargin
が適用されるようになり、要素を元通りにすることができました。
setTimeout(() => {
/* (11) */
el.style.removeProperty("height");
el.style.removeProperty("overflow");
el.style.removeProperty("transition-duration");
el.style.removeProperty("transition-property");
el.style.removeProperty("transition-timing-function");
}, duration);
- アニメーション完了後、必要なくなったプロパティを一斉に削除。
アニメーション完了後、いらなくなったプロパティをstyle属性から取り除きます。
これでslideDown
の解説は終わりです!
slideToggleの解説
最後にslideToggleの解説をしていきます。
slideToggle
は、要素が隠れている場合はスライドしながら表示、表示されている場合はスライドしながら非表示にする関数です。
まずはDEMOで動きを再確認しておきましょう。
slideUp / slideDown / slideToggleのDEMO
要素がスライドしながら表示/非表示を交互に切り替えるアニメーションが確認できたかと思います。
以下がslideToggle
の実装コードです。
const slideToggle = (el, duration = 300) => {
/* ① */
if (window.getComputedStyle(el).display === "none") {
/* ② */
return slideDown(el, duration);
} else {
/* ③ */
return slideUp(el, duration);
}
};
- 要素の
display
プロパティの値がnone
かどうかを判定。 none
の場合 =slideDown
関数を返して要素を表示する。none
以外の場合 =slideUp
関数を返して要素を隠す。
ここではまずクリックした段階で要素が表示されているかどうかを判別します。
もしdisplay
の値がnone
の場合、要素は非表示であるという意味になりますね。
その場合はslideDown
関数を返して要素を表示します。
反対に、display
の値がnone
以外の場合は、要素は表示されている状態なので、slideUp
関数を返して要素を隠します。
これでslideToggle
の解説は終わりです!
【まとめ】jQueryのslide系メソッドは素のJavaScriptで実装可能!
今回の記事では、jQueryのslideUp
, slideDown
, slideToggle
メソッドを素のJavaScriptで実装する方法を紹介しました。
jQueryは便利なライブラリですが、使用したくない場面もあるかと思います。
そういった場合は、今回紹介したコードをぜひ使ってみてください!
コメント
コメント一覧 (2件)
不明点がありましたのでご質問させて頂ければと存じます。
Slide Downのコードでel.style.removeProperty(“display”);の表記がございますが、
こちら必要でしょうか?
noneとblockの付け外しのみで良いような気がしたのですが、特別に記載している理由があれば
ご教示頂けたら幸いです。
// slideDown
const slideDown = (el, duration = 300) => {
el.style.removeProperty(“display”);
let display = window.getComputedStyle(el).display;
if (display === “none”) {
display = “block”;
宜しくお願い致します。
コメントありがとうございます!
おっしゃる通りで、もし’block’と’none’を切り替えたい場合はremovePropertyの記述は必要ありません。
しかし、’block’以外の値(例えば’flex’や’inline-block’など)にも対応したい場合は、必要になります。
以下で、’flex’と’none’を切り替えたい場合について説明しますね。
前提として、CSSは以下のようになっています。
○CSS
.element {
display: flex;
}
————————
■el.style.removeProperty(“display”);の記述がある場合
el.style.removeProperty(“display”); // 要素のstyleから’display:none’を削除
let display = window.getComputedStyle(el).display; // 要素のdisplayの値を取得(’flex’)
if (display === “none”) { // 変数displayには’flex’が入っているため{}内は適用されない
display = “block”;
}
el.style.display = display; // displayには’flex’が指定される
■el.style.removeProperty(“display”);の記述がない場合
let display = window.getComputedStyle(el).display; // 変数displayには、style属性の’none’が格納される(CSSの’display: flex’よりもスタイル属性が優先されるため)
if (display === “none”) { // 変数displayには’none’が入っているため{}内を適用(デフォルト値の’block’が指定される)
display = “block”;
}
el.style.display = display; // displayには’block’が指定される
————————
分かりづらい説明で申し訳ないです・・。
簡潔に言うと、removePropertyの行を記述しないと、CSS側で’flex’や’inline-block’を指定しても、slideDownを使用すると’block’になってしまうということです。
一度自身のコードで試していただくと、理解しやすいかと思います!