身为一个不那么优秀的后端程序员,我花了好几天,写了个前端的轮播图幻灯片,改了n多bug之后,大概没有bug了…
2020年7月12日更新计算方式,修复一些不算bug的bug.
比如有时候网页加载慢,会导致js计算的图片宽度有问题,拖动时两张图之间会有白色空隙.bug已解决.需要自己计算出图片的宽高比和图片与屏幕宽度的比率.
先上链接----
本轮播可以在电脑端鼠标拖动,手机端手指滑动,为了方便后端直接插入或者load进其他页面,连标签的名字我都改成了肯定不会与其他页面id或者class冲突的名字.
为了防止从第1张图点到第3张图时连续跳页,本轮播采用了不同于大部分网站轮播的方式,先将展示图的siblings标签分别挪到展示图两侧,点击后会在展示图两侧直接显示要展示的图,以防跳页.
举个例子,展示图是111,当点击右下角的333后,基本网上搜的大部分轮播都会跳两张图转到333,这个bug我一个后端程序员都忍不了了,本轮播,点了333,111右边不会出现222,直接就是333,点预览链接自己体会一下吧,我恨bug.
不要积分,不要毒盘,自己的服务器放的预览与下载链接
另外,作为一个后端程序员,我发誓,我再也不想写轮播了!!!
转载请注明出处
电脑端预览图
移动端预览图
html代码
<!doctype html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" name="viewport">
<meta content="ie=edge" http-equiv="X-UA-Compatible">
<title>轮播</title>
</head>
<style>
@media only screen and (min-width: 0) {
* {
margin: 0;
padding: 0;
}
#carouselUl li img {
width: 100%;
}
#cLeft,
#cRight {
background: #000000;
color: #fff;
font-size: 52px;
height: 80px;
line-height: 80px;
opacity: 0.3;
position: absolute;
text-align: center;
top: 50%;
transform: translateY(-50%);
width: 40px;
}
#cArrow #cLeft {
left: 0;
}
#cArrow #cRight {
right: 0;
}
#cBanner #cArrow {
display: none;
}
/* 鼠标经过 */
#cBanner:hover #cArrow {
cursor: pointer;
display: block;
}
#cBanner {
margin: 0 auto;
overflow: hidden;
position: relative;
text-align: center;
width: 100%;
}
#carouselUl {
list-style: none;
position: relative;
width: 100%;
}
#carouselUl li > div {
width: 100%;
}
#carouselUl li {
font-size: 37px;
position: absolute;
width: 100%;
}
/*小圆点样式*/
.pointerOl {
display: flex;
height: 60px;
list-style: none;
text-align: center;
}
.pointerOl li {
background-color: rgba(0, 0, 0, 0.2);
width: 25%;
}
.carouseOlLIDiv img {
width: 100%;
}
#cPoint {
bottom: 0;
margin: 0;
position: absolute;
width: 100%;
z-index: 12;
}
.carouseOlLIDiv {
cursor: pointer;
height: 100%;
text-align: center;
width: 100%;
}
.carouseOlLIDiv span {
display: inline-block;
height: 100%;
padding: 0 0 0 0;
width: 100%;
}
.carouseOlLIDiv > span > a > div {
margin: 6px 0 0 31px;
}
.carouseOlLIDiv > span > a {
color: white;
display: block;
height: 100%;
margin: 0 0 0 0;
text-align: left;
width: 100%;
}
#carouselUl li {
font-size: 200px;
width: 100%;
height: 100%;
display: none;
}
#carousel .pointNow {
background-color: rgba(32, 120, 189, 0.8);
/*display: block;*/
}
}
@media only screen and (max-width: 600px) {
#cLeft,
#cRight {
background: #000000;
color: #fff;
font-size: 52px;
height: 80px;
line-height: 80px;
opacity: 0.3;
position: absolute;
text-align: center;
top: 50%;
transform: translateY(-50%);
width: 40px;
}
.carouseOlLIDiv img {
width: 100%;
}
#cArrow #cLeft {
left: 0;
}
#cArrow #cRight {
right: 0;
}
/*鼠标经过盒子,让箭头显示出来*/
#cBanner:hover #cArrow {
cursor: pointer;
display: block;
}
#cBanner {
cursor: pointer;
overflow: hidden;
position: relative;
width: 100%;
}
#carouselUl {
list-style: none;
margin: 0 0 0 0;
padding: 0 0 0 0;
position: absolute;
width: 100%;
}
#carouselUl li {
float: left;
font-size: 115px;
position: absolute;
text-align: center;
width: 100%;
}
#carouselUl li img {
width: 100%;
}
#cPoint {
height: 30px;
}
/*小圆点样式*/
.pointerOl {
height: 30px !important;
list-style: none;
padding: 0;
text-align: center;
}
.pointerOl li {
background-color: rgba(0, 0, 0, 0.2);
display: inline-block;
height: 100%;
margin: 0 auto;
width: 24.7%;
}
.carouseOlLIDiv > img {
display: none;
margin: 0 0 0 -2px;
width: 100%;
}
.carouseOlLIDiv {
background-color: rgba(0, 0, 0, 0.2);
height: 100%;
text-align: center;
width: 98%;
}
.carouseOlLIDiv span {
display: inline-block;
font-size: 20px;
}
#cBanner #cArrow {
display: none;
}
/* 鼠标经过 */
#cBanner:hover #cArrow {
cursor: pointer;
display: block;
}
.carouseOlLIDiv {
cursor: pointer;
height: 100%;
text-align: center;
width: 100%;
}
.carouseOlLIDiv span {
display: inline-block;
height: 100%;
padding: 0 0 0 0;
width: 100%;
}
.carouseOlLIDiv > span > a > div {
font-size: 15px !important;
margin: 4px auto !important;
text-align: center;
}
.carouseOlLIDiv > span > a {
color: white;
display: block;
height: 100%;
margin: 0 0 0 0;
text-align: left;
width: 100%;
}
.pointerTitle {
display: block;
height: 30px;
}
}
</style>
<script src="https://wurenzhi.com/jq.js"></script>
<body>
<!-- 以下是轮播 -->
<div id='carousel'>
<div id='cBanner'>
<ul id='carouselUl'>
<li style="display: block" class='carouselNow' style='z-index: 10;'>111111</li>
<li>222222</li>
<li>333333</li>
<li>444444</li>
</ul>
<div id='cArrow'>
<span id='cLeft' style='z-index: 30;'><</span>
<span id='cRight' style='z-index: 30;'>></span>
</div>
</div>
<!--存放小圆点的图片-->
<div id='cPoint'>
<ol class='pointerOl'>
<li class='pointNow'>
<div class='carouseOlLIDiv'>
<span>
<a>
<div>
<p class='pointerTitle'>1111</p>
<p>1111</p>
</div>
</a>
</span>
</div>
</li>
<li>
<div class='carouseOlLIDiv'>
<span>
<a>
<div>
<p class='pointerTitle'>2222</p>
<p>2222</p>
</div>
</a>
</span>
</div>
</li>
<li>
<div class='carouseOlLIDiv'>
<span>
<a>
<div>
<p class='pointerTitle'>3333</p>
<p>3333</p>
</div>
</a>
</span>
</div>
</li>
<li>
<div class='carouseOlLIDiv'>
<span>
<a>
<div>
<p class='pointerTitle'>4444</p>
<p>4444</p>
</div>
</a>
</span>
</div>
</li>
</ol>
</div>
</div>
<!-- 以上是轮播 -->
</body>
<script>
// let ratioX = 90.2 / 100, ratioXY = 3.25; //图片缩放的大小,如果图片不占满全屏,就要计算一下ratioX,是图片实际展示宽度,ratioXY是宽高比
let ratioX = 100 / 100, ratioXY = 3.25;
let tBanner = $('#cBanner'), tLeft = $('#cLeft'), tRight = $('#cRight'), tWidth = $('html').width() * ratioX, tLi = $('#carouselUl>li'),
point = $('.pointerOl>li'), tIndex = 0, downX = 0, showIndex = getShowIndex(), clickFlag = true, screenWidth = window.screen.width;
changeSize();//浏览器缩放,大小改变检测
function changeSize() {
let imgHeight = $('html').width() * ratioX / ratioXY;
// console.log('图片宽度: ' + imgHeight);
$('#carouselUl').css('height', imgHeight);
}
//拖动方法 //先遍历
$.each(tLi, function (index) {//console.log(screenWidth, screenHeight);
if (screenWidth <= 600) {//判断屏幕宽度,如果小于600,执行touch函数,不执行鼠标点击移动函数 /**注意调用的方法不要加括号()*/
tLi.eq(index)[0].addEventListener('touchstart', touchstartFun);
tLi.eq(index)[0].addEventListener('touchmove', touchmoveFun);
tLi.eq(index)[0].addEventListener('touchend', touchendFun);
//添加的touch方法
function touchstartFun(e) {
let lenX = e.targetTouches[0].clientX; //console.log("触摸按下: " + index, lenX, lenX);
pressFun(index, e, lenX);
}
function touchmoveFun(e) {
let lenX = e.targetTouches[0].clientX;
liMoveFun(e, lenX);
}
function touchendFun(e) {
let lenX = e.changedTouches[0].clientX;
loosen(e, lenX);
}
} else {//屏幕宽度大于600,执行鼠标移动函数
tLi.eq(index).on('mousedown', function (e) {
pressFun(index, e); //执行按下的外部函数 //点击遍历的图片
$(document).mousemove(function move(ev) { liMoveFun(ev); }); //执行移动的外部函数
$(document).unbind('mouseup').mouseup(function (eve) { loosen(eve); });//执行抬起的外部函数
});
}
});
//外部函数按下
function pressFun(index, e, phoneX) {
e.preventDefault(); //去除默认事件//console//console.log("flag变成true");
e.stopPropagation(); //去除冒泡 //console.log("鼠标按下");
tIndex = index;//console.log("点击了第" + index);
clickFlag = true;//点击拖动轮播中的某个图片
if ($('#carouselUl li:animated').length) return;//console.log("动画在进行");
showIndex = getShowIndex();
if (!phoneX) {//获取鼠标位置 //如果没有第三个参数,就是鼠标操作
if (e.pageX) downX = e.pageX;
else if (e.clientX) downX = e.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
} else downX = phoneX;
}
//外部函数移动
function liMoveFun(e, phoneX) {
// console.log('上一个的左距: ' + tLi.eq(before).css('left'));
// console.log('下一个的左距: ' + tLi.eq(after).css('left'));
e.stopPropagation();//console.log("执行了move");
let posX = 0; //console.log("鼠标移动");
e = e || window.event;
if (!phoneX) {//获取鼠标位置
if (e.pageX) posX = e.pageX;
else if (e.clientX) posX = e.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
} else posX = phoneX;
let moveX = posX - downX;//获取移动距离
tLi.eq(showIndex).css({'left': moveX}); //图片跟随鼠标的移动痕迹
let before, after;
if (showIndex !== 0 && showIndex !== 3) before = showIndex - 1, after = showIndex + 1;
else if (showIndex === 0) before = 3, after = 1;
else if (showIndex === 3) before = 2, after = 0;
// console.log('移动距离: ' + moveX + ' 图标距离左侧: ' + tLi.eq(showIndex).css('left'), '上一个的左距: ' + tLi.eq(before).css('left'), '下一个的左距: ' + tLi.eq(after).css('left'));
tLi.eq(before).show().css({'z-index': 9, 'left': -tWidth + moveX});
tLi.eq(after).show().css({'z-index': 9, 'left': tWidth + moveX});
}
//外部函数抬起
function loosen(e) {
e.stopPropagation(); //去除冒泡// let cssLeftPx = tLi.eq(showIndex).css('left');
let cssLeft = tLi.eq(showIndex).position().left;//parseInt(cssLeftPx); // console.log('leftPx: ' + cssLeftPx + 'jq直接left: ' + tLi.eq(showIndex).position().left);
if (cssLeft === 0) clickFlag = false;
let before, after; //计算
if (showIndex !== 0 && showIndex !== 3) before = showIndex - 1, after = showIndex + 1;
else if (showIndex === 0) before = 3, after = 1;
else if (showIndex === 3) before = 2, after = 0;
if (clickFlag) {
if (cssLeft > (tWidth / 3)) {//显示左边的
clickFlag = false;//console.log("显示左边的");
tLi.eq(before).addClass('carouselNow').animate({'left': 0}, 200).siblings().removeClass('carouselNow');
tLi.eq(showIndex).animate({'left': tWidth}, 200, function () { $(this).hide(); });
tLi.eq(after).animate({'left': tWidth}, 200, function () { $(this).hide(); });
if (showIndex <= 0) { showIndex = 3; } else if (showIndex >= 3) { showIndex = 0; } else { showIndex--; }
tIndex = showIndex;
}
//显示右边的
else if (cssLeft <= 0 && cssLeft <= ((-tWidth / 3))) {//console.log("显示右边的");
clickFlag = false;
tLi.eq(before).animate({'left': -tWidth}, 200, function () { $(this).hide(); });
tLi.eq(showIndex).animate({'left': -tWidth}, 200, function () { $(this).hide(); });
tLi.eq(after).addClass('carouselNow').animate({'left': 0}, 200).siblings().removeClass('carouselNow');
if (showIndex <= 0) { showIndex = 3; } else if (showIndex >= 3) { showIndex = 0; } else { showIndex++; }
tIndex = showIndex;
} else {//console.log("归位");
clickFlag = false;
tLi.eq(showIndex).animate({'left': 0}, 200); //把其他的复位
//计算index
// tLi.eq(before).css({'z-index': 2});
tLi.eq(before).css({'z-index': 2}).animate({'left': -tWidth}, 200, function () { $(this).hide(); });
// tLi.eq(after).css({'z-index': 2});
tLi.eq(after).css({'z-index': 2}).animate({'left': tWidth}, 200, function () { $(this).hide(); });
}
clickMark(getShowIndex());
}
//去除鼠标移动监听
$(document).unbind('mousemove');
$(document).unbind('mouseUp');
}
//小圆点标记显示
function clickMark(clickMarkIndex) {
point.eq(clickMarkIndex).css({'background-color': 'rgb(32, 120, 189,0.8)'})
.siblings().css({'background-color': 'rgba(0, 0, 0, 0.2)'});
}
//小圆点悬浮
point.on('click', function yuandian() {
if ($('#carouselUl li:animated').length) return;
showIndex = getShowIndex();
let index = $(this).index();//点击的index
$(this).css({'background-color': 'rgba(32, 120, 189,0.8)'}).siblings().css({'background-color': 'rgba(0, 0, 0, 0.2)'});//将本条li变色
if (showIndex === index) return;//如果当前和要显示的一致,就不执行
(index > showIndex) ? moveToWhere(index, -tWidth, tWidth) : moveToWhere(index, tWidth, -tWidth);
tIndex = index;// 赋值点击的index给全局
});
let time = setInterval(function () { tRight.click(); }, 500000);//调取carouselRight方法,使其自动播放
tBanner.mouseenter(function () { clearInterval(time); });//鼠标移到carouselBanner中,自动播放停止
tBanner.mouseleave(function () { time = setInterval(function () { tRight.click(); }, 500000); });// 鼠标移出carouselBanner中,自动播放开始
function getShowIndex() { //获取当前正显示的图片的下表
return $('#carouselUl').children('.carouselNow').index();
}
$(window).resize(function () {
changeSize();
});
//点击右箭头, ul往左跑
tRight.on('click', function () {
// console.log('右箭头判断有动画,不执行');
if ($('#carouselUl li:animated').length) return;
if (tIndex >= 3) tIndex = 0;
else tIndex++;
//执行移动方法
moveToWhere(tIndex, -tWidth, tWidth);
clickMark(tIndex);
});
//点击左箭头,让carouselUl往右跑
tLeft.on('click', function () {
// console.log('动画进行中,停止左点');
if ($('#carouselUl li:animated').length) return;
if (tIndex <= 0) tIndex = 3;//console.log("左边" + tIndex + 1);
else tIndex--;
//执行移动方法
moveToWhere(tIndex, tWidth, -tWidth);
clickMark(tIndex);
});
//移动方法函数
function moveToWhere(index, widthMinus, wid) {
// console.log('移动方法函数: ' + index, widthMinus, wid);
let tl = tLi.eq(index);
tl.siblings().animate({'left': widthMinus}, function () { $(this).hide(); });
tl.show().css('left', wid).animate({'left': 0});
tl.addClass('carouselNow').siblings().removeClass('carouselNow');
showIndex = getShowIndex();
}
</script>
</html>