【jQueryを完全再現】slideUp, slideDown, slideToggleを素のJavaScriptで実装する方法
【jQueryを完全再現】slideUp, slideDown, slideToggleを素のJavaScriptで実装する方法 2021 4/07 JavaScript 2021年3月28日2021年4月7日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 Vanilla JavaScriptで実装したslideUp / slideDown / slideToggleのDEMO jQueryで実装した場合のDEMO続いてはjQueryのslideUp・slideDown・slideToggleを使用したDEMOです。
jQueryには、これらのメソッドがはじめから用意されていますね。
slideUp slideDown slideToggle 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 Vanilla JavaScriptで実装した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を指定。
- 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 Vanilla JavaScriptで実装した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属性に設定。
- transition-property,transition-duration ,transition-timing-functionをそれぞれ設定。
- 親要素からはみ出す部分を非表示にするoverflow: hiddenを指定。
- ⑤で取得した高さを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 Vanilla JavaScriptで実装した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は便利なライブラリですが、使用したくない場面もあるかと思います。
そういった場合は、今回紹介したコードをぜひ使ってみてください!
あわせて読みたい 素のJavaScriptでアニメーション付きアコーディオンを実装する方法【3通り】 Webサイト上では、アコーディオンメニューがよく使われていますよね。 コンテンツを折り畳むことができるため、 ユーザーが欲しい情報をピンポイントで探せるページが縦…Web制作のメンターをお探しですか?
Web制作の学習&お悩み解決をサポートするメンターサービスを開始しました。
Web制作を学びたい方は、ぜひMENTAからご相談ください!
MENTAで相談する JavaScript よかったらシェアしてね!- URLをコピーしました!
- URLをコピーしました!