もくじ
「Swiper.js」を使用してループ付きスライダーを実装する際、前後ボタンをクリックした時のスライド切り替えが遅いと感じることがあります。
本記事では、前後ボタンの切り替え速度を調整するためのコードを紹介します。
- 「swiper.js」のバージョンについて
v11のCDNを使用
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css">
<script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>
最新のCDNバージョンは、以下公式サイトでご確認いただけます。
https://swiperjs.com/get-started#use-swiper-from-cdn
前後ボタンのクリック時の切り替え速度を調整する理由
Swiper.jsでループをさせてない場合、オプションにrunCallbacksOnInit: true
を設定することで、前後ボタンクリック時、スライドを即時切り替えることができます。
しかし、ループさせている場合、スライドの切り替えが完了するまで前後ボタンをクリックしても反応しなくなります。
特にスライドの切り替え速度(speed
)を遅く設定している場合に目立ちます。
【サンプル】スライドの切り替えが完了するまで前後ボタンが反応しない場合の例
【サンプルコード】スライドの切り替えが完了するまで前後ボタンが反応しない場合の例
別途、Swiperを使用するためのライブラリを読み込む必要があります。
※以下のコードだけでは、swiperは起動しません。
<div class="swiper-sample">
<div class="swiper-wrapper">
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
<div class="swiper-slide">Slide 4</div>
<div class="swiper-slide">Slide 5</div>
</div>
<!-- ナビゲーションボタン -->
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
</div>
.swiper-sample {
position: relative;
overflow: hidden;
}
.swiper-wrapper .swiper-slide {
height: 150px;
display: flex;
justify-content: center;
align-items: center;
}
.swiper-slide {
background-color: #fff0f0;
}
.swiper-sample .swiper-button-next,
.swiper-sample .swiper-button-prev {
width: 40px;
height: 40px;
border-radius: 100%;
background: #f09896;
top: 50%;
}
.swiper-sample .swiper-button-next:after,
.swiper-sample .swiper-button-prev:after {
color: #fff;
font-size: 15px;
}
(function() {
let speed = 4000;
const swiperSample = new Swiper('.swiper-sample', {
loop: true,
slidesPerView: 2,
spaceBetween: 30,
speed: speed, // スライド切り替え速度
autoplay: {
delay: 6000, // 切り替え間隔(ミリ秒)
disableOnInteraction: false, // ユーザー操作後も自動再生を継続
},
navigation: {
nextEl: '.swiper-sample .swiper-button-next',
prevEl: '.swiper-sample .swiper-button-prev',
},
});
})();
【サンプル】前後ボタンの切り替えを即時できるように調整
【実装コード】前後ボタンの切り替えを即時できるように調整
別途、Swiperを使用するためのライブラリを読み込む必要があります。
※以下のコードだけでは、swiperは起動しません。
<div class="swiper">
<div class="swiper-wrapper">
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
<div class="swiper-slide">Slide 4</div>
<div class="swiper-slide">Slide 5</div>
</div>
<!-- ナビゲーションボタン -->
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
</div>
.swiper {
position: relative;
overflow: hidden;
}
.swiper-wrapper .swiper-slide {
height: 150px;
display: flex;
justify-content: center;
align-items: center;
}
.swiper-slide {
background-color: #fff0f0;
}
.swiper .swiper-button-next,
.swiper .swiper-button-prev {
width: 40px;
height: 40px;
border-radius: 100%;
background: #f09896;
top: 50%;
}
.swiper .swiper-button-next:after,
.swiper .swiper-button-prev:after {
color: #fff;
font-size: 15px;
}
(function() {
let speed = 4000;
let clickNavSpeed = 500; // ナビゲーションクリック時のスライド切り替え速度
let slidesPerGroup = 1; // 一度にスライドさせる枚数
const swiper = new Swiper('.swiper', {
loop: true,
slidesPerView: 2,
slidesPerGroup: slidesPerGroup,
spaceBetween: 20,
speed: speed, // スライド切り替え速度
autoplay: {
delay: 6000, // 切り替え間隔(ミリ秒)
disableOnInteraction: false, // ユーザー操作後も自動再生を継続
},
});
let clickFlag = false;
let isSliding = false;
// 前へボタン
document.querySelector('.swiper .swiper-button-prev').addEventListener('click', () => {
ajust_slide('prev');
});
// 次へボタン
document.querySelector('.swiper .swiper-button-next').addEventListener('click', () => {
ajust_slide('next');
});
swiper.on('slideChangeTransitionStart', function() {
isSliding = true;
if (clickFlag) {
swiper.wrapperEl.style.transition = clickNavSpeed + 'ms';
}
});
swiper.on('slideChangeTransitionEnd', function() {
isSliding = false;
if (clickFlag) {
clickFlag = false;
swiper.update();
swiper.autoplay.start();
}
});
function ajust_slide(p) {
const swiperTransform = swiper.wrapperEl.style.transform.match(/translate3d\((-?\d+\.?\d*)px, (-?\d+\.?\d*)px, (-?\d+\.?\d*)px\)/);
if (swiperTransform && isSliding && !clickFlag) {
// 現在のtranslateを取得
const getTranslate = swiper.getTranslate();
// アニメーションの停止
swiper.setTranslate(getTranslate);
swiper.setTransition(0);
let x; // 次の位置の計算
if (p === 'prev') {
x = parseFloat(swiperTransform[1]) + getFullWidth(swiper.slides[0]) * slidesPerGroup;
} else {
x = swiperTransform[1];
}
setTimeout(() => {
swiper.wrapperEl.style.transition = clickNavSpeed + 'ms';
swiper.wrapperEl.style.transform = 'translate3d(' + x + 'px, 0px, 0px)';
}, 0);
if (p === 'prev') {
// Swiper の状態を手動で更新
swiper.activeIndex -= slidesPerGroup;
// ループ処理のための修正
if (swiper.activeIndex < 0) {
swiper.activeIndex = swiper.slides.length - slidesPerGroup * 2; // ループ時の補正
} else if (swiper.activeIndex >= swiper.slides.length - slidesPerGroup) {
swiper.activeIndex = slidesPerGroup; // ループ時の補正
}
// realIndex` を手動で再計算
swiper.realIndex = swiper.activeIndex % swiper.slides.length;
// Swiper の内部状態を更新
clickFlag = true;
setTimeout(() => {
swiper.emit('slideChangeTransitionEnd');
}, clickNavSpeed);
return;
}
clickFlag = true;
return;
}
// アニメーションが発生していない場合、通常の動作
clickFlag = true;
if (p === 'prev') {
swiper.slidePrev();
} else {
swiper.slideNext();
}
}
function getFullWidth(element) {
const style = window.getComputedStyle(element);
const marginLeft = parseFloat(style.marginLeft);
const marginRight = parseFloat(style.marginRight);
const totalWidth = element.offsetWidth + marginLeft + marginRight;
return totalWidth;
}
})();
注意事項
- Swiper.jsのバージョンによっては機能しない可能性があります。
- Swiper.jsのオプション(設定項目)によっては機能しない可能性があります。
- Swiper.jsに対して独自のJavaScriptカスタマイズを追加した場合、Swiper.jsの更新やオプション設定の変更によって動作が影響を受ける可能性があります。
udemyでJavaScriptを学ぶ
- 本格的なWEBサイトを作成する方法について学びます。
- Sass(※以下CSSと記載)、JavaScriptの基礎について深く学びます。
- CSS、JavaScriptの実践的な記述について深く学びます。
- CSS、JavaScriptアニメーションの実装について学びます。
- 最新の実践的なWEB画面の作成方法について深く学びます。
- CSS、JavaScriptのコードの最適化、安定化について学びます。
- 維持管理、持続可能なコードの記述方法について学びます。
- ドットインストールでCSS、JavaScriptの入門編を終えたレベルの方
- 他の先生のフロントエンドの入門編を終えたレベルの方
- 自分で本格的なWEBサイトを作ってみたい方
- CSS、JavaScriptの実践的な基礎を効率的に学びたい方
- CSS、JavaScriptを今後仕事で使う予定の方
- CSS、JavaScriptのコードの整理方法について学びたい方
- CSS、JavaScriptのアニメーションを学びたい方
- CSS、JavaScriptのレベルアップしたいWeb開発初級者の方
- CSS、JavaScriptでどのようにすればレベルアップできるのか悩んでいる方
- JavaScriptの動作原理について深く学びます。
- JavaScriptがどのように実行されるのかについて深く学びます。
- ES6+の最新のJavaScriptの記法について幅広く学びます。
- 変数や参照の仕組みについて深く学びます。
- オブジェクトのメカニズムについて深く学びます。
- 関数のメカニズムについて深く学びます。
- スコープの仕組みについて深く学びます。
- プロトタイプのメカニズムについて深く学びます。
- 反復処理のメカニズムについて深く学びます。
- ジェネレーターやイテレーターについて深く学びます。
- コールバック関数について深く学びます。
- 非同期処理のメカニズムについて深く学びます。
- モジュールの仕組みについて深く学びます。
- クロージャーの仕組みについて深く学びます。
- レキシカルスコープの仕組みについて深く学びます。
- アロー関数の特徴について深く学びます。
- レキシカルスコープの仕組みについて深く学びます。
- アロー関数の特徴について深く学びます。
- thisの仕組みについて深く学びます。
- bind、apply、callの動作原理について深く学びます。
- クラスと継承の仕組みについて深く学びます。
- ReflectやProxyなどの強力なオブジェクトへの理解を深めます。
- Map,Setなどの強力なコレクションについて実践を交えて学びます。
- よく使用される強力な実装パターンを演習を交えて学びます。
- 独自のフレームワークを構築していく中でJavaScriptのメカニズムについて理解を深めます。
- JavaScriptをコアの動作原理からキチンと理解したい方。
- 自分の思った通りコードが動かずに悩んでいる方。
- 自分の思った通りに動かず、気付いたら解決するのに1日経ってしまっていた経験のある方。
- React, Vue, Angularが使いこなせず悩んでいる方。
- JavaScriptの不可解な動きが理解できず、苦しんでいる方。
- 少し複雑なコードを書こうとすると、ぐちゃぐちゃになって整理しきれず、悩んでいる方。
- JavaScriptを本気で勉強したいと思っている方。
- JavaScriptの変態仕様に苦しんでいる方。
- JavaScriptが苦手なプログラマーの方。
もみじ
JavaScripの基礎的なことを理解しており、より深くJavaScriptについて理解したいという方にオススメの講座です。
初心者の方が一度の受講で全てを吸収するのは難しいですが、繰り返し受講することでフロントエンドの業務で役立つ知識を身に付けることができます。
HTMLとCSSの知識がありJavaScriptを学びたいという方におすすめの1冊
もみじ
HTMLとCSSの知識がありJavaScriptを学びたいという方に入門書としておすすめの書籍です。
実務で役立つサンプルを手を動かしながら学ぶことができ、実践的なスキルを身に付けることができます。
JavaScriptのフロントエンドエンジニアを目指している方におすすめの1冊
もみじ
この本はJavaScript初心者からフロントエンドエンジニアを目指す方にぴったりの1冊です。
非同期処理やAJAXなど、現代の開発で必要なスキルがわかりやすく解説されており、実務で役立つスキルを学ぶことができます。
もみじ
HTML・CSS・JavaScripの基礎的なことを理解しており、Webのフロントエンジニアを目指している方にオススメの講座です。
講座内容は実践で使用するものが多く、実務でも役立つ内容でした。