接上一篇,第一個問題:我們要考慮圖片數量,當圖片數量<=1時,不顯示指示器:
//第二步:添加指示器
var indicator_li = null;
if (banner_li.length > 1) {
var ul_indicator = document.getElementById("ul_indicator");
var indicatorHtml = "";
for (let i = 0; i < banner_li.length - 2; i++) {//要按原來的圖片數量
indicatorHtml += "<li></li>"
}
ul_indicator.innerHTML = indicatorHtml;
indicator_li = ul_indicator.getElementsByTagName("li");
}
第二個問題:實現移動端手勢滑動操作:監聽觸摸操作,我們需要用到addEventListener方法,並且需要監聽至少三個手勢:
按下:關閉定時器並記錄手指落點座標
ul_banner.addEventListener("touchstart", function () {
})
滑動:根據滑動動態座標與手指落點座標計算動態滑動距離
ul_banner.addEventListener("touchmove", function () {
})
擡起:做一些還原操作如再次開啓定時器
ul_banner.addEventListener("touchend", function () {
})
另外要計算好,手指在屏幕滑動的距離,即
moveX=手指擡起點-手指落點
手指往右滑動,輪播圖往左移動,moveX就爲負數,反之爲正數,因爲我們上面的屬性left用的是百分比(也可以用px具體值),所以我們要根據滑動距離/屏幕寬度計算滑動的百分比,再加上原來的ul偏移的百分比得到最終的left偏移量!
另外一個優化點是,手指滑動圖片擡起後,圖片的位置該如何顯示?我這裏是做了一個判斷處理,如果滑動圖片距離超過50%,則在擡起時自動滑動到上一個或下一個圖片,如果未到50%,則還原。
瞭解滑動原理及計算方法後,其實下面就很好寫了:
function bannerCarousel() {
// 第一步:獲取banner li img列表,將列表第一張圖片複製添加到最後一位,最後一張圖片複製添加到第一位;
//以本例4張圖片爲例,將第4張圖片複製一份放到第一位,將第1張圖片放置到最後一位,最後得到6張圖片,
// 這樣每次輪播到position=0或者5時,將其位置重置爲4或1,以實現無限滾動輪播
var ul_banner = document.getElementById("ul_banner");
var banner_li = ul_banner.getElementsByTagName("li");
var banner_li_first = banner_li[0];
var banner_li_last = banner_li[banner_li.length - 1];
ul_banner.appendChild(banner_li_first.cloneNode(true));//將第一張圖片複製一份添加到最後一位
ul_banner.insertBefore(banner_li_last.cloneNode(true), ul_banner.firstChild);//將最後一張圖片複製一份添加到第一位
ul_banner.style.width = banner_li.length * 100 + "%";//寬度爲6張圖片寬度
for (let i = 0; i < banner_li.length; i++) {
banner_li[i].style.width = 100 / banner_li.length + "%";
}
ul_banner.style.left = "-100%";//因首位添加圖片後,需要將整體定位到第2張圖片(實際爲banner第一張)
//第二步:添加指示器
var indicator_li = null;
if (banner_li.length > 1) {
var ul_indicator = document.getElementById("ul_indicator");
var indicatorHtml = "";
for (let i = 0; i < banner_li.length - 2; i++) {//要按原來的圖片數量
indicatorHtml += "<li></li>"
}
ul_indicator.innerHTML = indicatorHtml;
indicator_li = ul_indicator.getElementsByTagName("li");
}
//第三步:開啓定時器
var page_index = 1;//初始位置爲1
var timer = function () {
page_index++;
ul_banner.style.transition = "left 0.5s";
ul_banner.style.left = -page_index * 100 + "%";
changeIndicator();
reLoadPosition();
};
var interval = setInterval(timer, 2000);
//指示器改變
var changeIndicator = function () {
if (indicator_li != null) {
for (var i = 0; i < indicator_li.length; i++) {
indicator_li[i].style.backgroundColor = "#ccc";
}
if (page_index === 0 || page_index === banner_li.length - 2) {//最後一張
indicator_li[banner_li.length - 3].style.backgroundColor = "#fff";
} else if (page_index === banner_li.length - 1) {
indicator_li[0].style.backgroundColor = "#fff";
} else {
indicator_li[page_index - 1].style.backgroundColor = "#fff";
}
}
}
//重置banner位置
var reLoadPosition = function () {
setTimeout(function () {//延時操作,等待0.5s動畫執行完畢後再執行以下操作
if (page_index === 0) {
page_index = banner_li.length - 2;
ul_banner.style.transition = "none";
ul_banner.style.left = (-page_index * 100) + "%";
} else if (page_index === banner_li.length - 1) {
page_index = 1;
ul_banner.style.transition = "none";
ul_banner.style.left = (-page_index * 100) + "%";
}
}, 500);
}
//滑動監聽
var screenW = window.screen.width;
var startX, w_current_percent, w_move_percent;
ul_banner.addEventListener("touchstart", function () {
clearInterval(interval);
var touch = event.targetTouches[0];
startX = touch.clientX;
w_current_percent = -page_index * 100;//當前left的百分比
});
ul_banner.addEventListener("touchmove", function () {
var touch = event.targetTouches[0];
var moveX = touch.clientX - startX;
w_move_percent = moveX / screenW * 100;//跟隨手指移動的百分比
ul_banner.style.transition = "none";//重要:一定不要忘記清除過渡效果
ul_banner.style.left = (w_current_percent + w_move_percent) + "%";
});
ul_banner.addEventListener("touchend", function () {
//如果左右滑動<寬度一般,則還原爲原來的位置,否則,滑動到上一位或下一位
if ((w_move_percent < 50 && w_move_percent > 0) || (w_move_percent < 0 && w_move_percent > -50)) {
ul_banner.style.left = w_current_percent + "%";
} else if (w_move_percent > 50) {//往右滑動一位
page_index--;
ul_banner.style.transition = "left 0.5s";
ul_banner.style.left = (w_current_percent + 100) + "%";
changeIndicator();
reLoadPosition();
} else if (w_move_percent < -50) {//往左滑動一位
page_index++;
ul_banner.style.transition = "left 0.5s";
ul_banner.style.left = (w_current_percent - 100) + "%";
changeIndicator();
reLoadPosition();
}
interval = setInterval(timer, 2000);
});
}
其中重要的一點,在move過程中,一定不要忘了清除過渡效果:
ul_banner.style.transition = "none";
難點或者複雜點其實就是,滑動距離的計算,手指擡起時圖片位置顯示計算,以及指示器顯示計算,這幾點弄明白後,實現起來就不在話下了!