ホームページ >ウェブフロントエンド >jsチュートリアル >ネイティブ JS を使用してモバイル Web カルーセル効果を実現する方法の詳細な説明
モバイル開発を行う場合、カルーセルグラフィックスは不可欠です。次の記事では、純粋なJSを使用してモバイルWebカルーセルグラフィックスを実現するための関連情報を主に紹介します。重要なのは、ホイールを作成するためにTweenアルゴリズムを組み合わせることです。サンプルコードを通じて詳しく説明します。必要な場合は、一緒に見てみましょう。
前書き
モバイル端末上のカルーセル画像は私たちのより一般的なニーズであることを誰もが知っておくべきだと思いますが、それらを実装する最速の方法は、多くの場合、スワイパーなどのサードパーティのコードを使用することですが、いくつかの比較に遭遇した場合。複雑なカルーセルが必要な場合、多くの場合、それを変更する方法がわかりません。そのため、さまざまな複雑で変化するニーズに適応するために、いくつかのホイールを自分で作成する必要があります。ポイントは、私たちが書いたコードにバグがある場合、修復するのが非常に簡単で、コード自体が大幅に改善されたということです
1. カルーセル画像さまざまな状況に適応する必要があります 幅/奥行き画面
2. タッチ関連のイベントを使用する必要があります
3. モデルごとにタッチイベントのサポートが異なり、互換性の問題が発生する可能性があります
4.画像の距離の一部を指でなぞり、残りの距離は自動的に完了する必要があります
5. 距離を自動的に完了するにはイーズタイムカーブが必要です
1. 指タッチイベントは、touchstart、touchmove、touchend の 3 つのイベントを通じて実現できます。
2. 開始 x 座標をタッチするときに指を記録する必要があり、今回は touch の pageX 属性を使用できます。ポイント、
3. 指が移動するとき、最初の 2 つのステップで計算された x 方向の移動距離、時点の差に基づいて、ページ ポイントを記録する必要もあります
5. の方向を決定します。 x方向に移動した距離を比較して次の画像に切り替えるかどうかを判断する; 時間に基づいてユーザーが進むかどうかを判断する 左右にスワイプする操作
6. 移動画像はtranslate3dとを使用して実現できます。ハードウェア アクセラレーションをオンにする
7. 一定の距離を移動するには、easeOut エフェクトを使用して、毎回の移動距離を認識できます。 もちろん、js を使用してトランジション アニメーションを設定することもできます。
実装ソースコード(参考のみ):
head style
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=.5,maximum-scale=.5">
<title>移动端轮播图</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0
}
.banner {
overflow: hidden;
width: 100%;
height: 300px
}
.banner .img-wrap {
position: relative;
height: 100%
}
.banner img {
display: block;
position: absolute;
top: 0;
width: 100%;
height: 100%
}
</style>
</head>
HTML構造
<p class="banner">
<p class="img-wrap" id="imgWrap">
<img src="images/banner_3.jpg" data-index="-1">
<img src="images/banner_1.jpg" data-index="0">
<img src="images/banner_2.jpg" data-index="1">
<img src="images/banner_3.jpg" data-index="2">
<img src="images/banner_1.jpg" data-index="3">
</p>
</p>
JS コード 1、easeOut アニメーションの動き、
ここで、HTMLElement.prototype.tweenTranslateXAnimate は、すべての HTML 要素クラスに拡張された tweenTranslateXAnimate メソッドです
一定の距離を移動するには、この反復的な操作を完了するためにタイマーを使用する必要があります
<script> HTMLElement.prototype.tweenTranslateXAnimate = function (start, end, callback) { var duration = 50; var t = 0; var vv = end - start; var Tween = { Quad: { easeOut: function (t, b, c, d) { return -c * (t /= d) * (t - 2) + b; } } }; this.timer = setInterval(function () { var dis = start + Tween.Quad.easeOut(++t, 0, vv, duration); this.style.transform = 'translate3d(' + dis + 'px, 0, 0)'; if (vv > 0 && parseInt(this.style.transform.slice(12)) >= end) { this.style.transform = 'translate3d(' + parseInt(dis) + 'px, 0, 0)'; clearInterval(this.timer); callback && callback(); } if (vv < 0 && parseInt(this.style.transform.slice(12)) <= end) { this.style.transform = 'translate3d(' + parseInt(dis) + 'px, 0, 0)'; clearInterval(this.timer); callback && callback(); } }.bind(this), 4); } </script>
タッチイベント部分
<script>
~function () {
var lastPX = 0; // 上一次触摸的位置x坐标, 需要计算出手指每次移动的一点点距离
var movex = 0; // 记录手指move的x方向值
var imgWrap = document.getElementById('imgWrap');
var startX = 0; // 开始触摸时手指所在x坐标
var endX = 0; // 触摸结束时手指所在的x坐标位置
var imgSize = imgWrap.children.length - 2; // 图片个数
var t1 = 0; // 记录开始触摸的时刻
var t2 = 0; // 记录结束触摸的时刻
var width = window.innerWidth; // 当前窗口宽度
var nodeList = document.querySelectorAll('#imgWrap img'); // 所有轮播图节点数组 NodeList
// 给图片设置合适的left值, 注意 querySelectorAll返回 NodeList, 具有 forEach方法
nodeList.forEach(function (node, index) {
node.style.left = (index - 1) * width + 'px';
});
/**
* 移动图片到当前的 tIndex索引所在位置
* @param {number} tIndex 要显示的图片的索引
* */
function toIndex(tIndex) {
var dis = -(tIndex * width);
var start = parseInt(imgWrap.style.transform.slice(12));
// 动画移动
imgWrap.tweenTranslateXAnimate(start, dis, function () {
setTimeout(function () {
movex = dis;
if (tIndex === imgSize) {
imgWrap.style.transform = 'translate3d(0, 0, 0)';
movex = 0;
}
if (tIndex === -1) {
imgWrap.style.transform = 'translate3d(' + width * (1 - imgSize) + 'px, 0, 0)';
movex = -width * (imgSize - 1);
}
}, 0);
});
}
/**
* 处理各种触摸事件 ,包括 touchstart, touchend, touchmove, touchcancel
* @param {Event} evt 回调函数中系统传回的 js 事件对象
* */
function touch(evt) {
var touch = evt.targetTouches[0];
var tar = evt.target;
var index = parseInt(tar.getAttribute('data-index'));
if (evt.type === 'touchmove') {
var di = parseInt(touch.pageX - lastPX);
endX = touch.pageX;
movex += di;
imgWrap.style.webkitTransform = 'translate3d(' + movex + 'px, 0, 0)';
lastPX = touch.pageX;
}
if (evt.type === 'touchend') {
var minus = endX - startX;
t2 = new Date().getTime() - t1;
if (Math.abs(minus) > 0) { // 有拖动操作
if (Math.abs(minus) < width * 0.4 && t2 > 500) { // 拖动距离不够,返回!
toIndex(index);
} else { // 超过一半,看方向
console.log(minus);
if (Math.abs(minus) < 20) {
console.log('距离很短' + minus);
toIndex(index);
return;
}
if (minus < 0) { // endX < startX,向左滑动,是下一张
toIndex(index + 1)
} else { // endX > startX ,向右滑动, 是上一张
toIndex(index - 1)
}
}
} else { //没有拖动操作
}
}
if (evt.type === 'touchstart') {
lastPX = touch.pageX;
startX = lastPX;
endX = startX;
t1 = new Date().getTime();
}
return false;
}
imgWrap.addEventListener('touchstart', touch, false);
imgWrap.addEventListener('touchmove', touch, false);
imgWrap.addEventListener('touchend', touch, false);
imgWrap.addEventListener('touchcancel', touch, false);
}();
</script>
touch イベントで最も重要なパラメータは、x の位置を記録する pageX パラメータです。
以上がネイティブ JS を使用してモバイル Web カルーセル効果を実現する方法の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。