在官网的的轮播图:
具体的需求:
1、轮播图每间隔7秒滚动一次
2、每一次滚动下面的滚动条的样式发生相应的变化
3、有两个点击事件(官方/合作)点击之后切换到不同的轮播图;图中展示的官方对应的轮播图,切换到合作的时候也会出现与之对应的轮播图展示页
一 设计HTML与CSS的思路(在布局时尽量使用标准流布局的方式)
a.最外层大盒子的设计思路:不做任何定位/浮动的布局处理,这样他就是标准流不会影响到其他兄弟盒子的布局,仅仅为其设置宽高就可以了
b.第一个子盒子sliders-cont这个盒子的大小与col-2的大小一致,但是这里给这个盒子加上相对定位,嵌在里面的子盒子就可以做定位布局,而不会影响与col-2盒子对应的兄弟盒子的布局.
c.第二个子盒子(与sliders-cont是兄弟关系),.slide-type切换模式的盒子,目的是用来切换与之对应的不同轮播图.注意这里使用绝对定位来控制盒子的位置,但是它的层级设置为z-index:999;目的是防止其他定位盒子的层级比它高,出现被覆盖的情况,因为这个盒子是用户一直可以用来点击切换的,如果被覆盖,用户点击不到,z-index也可以是比其他定位盒子层级高的数值,这里是以防万一.
d.slider-img-box盒子的大小与它的父盒子sliders-cont与父盒子的父盒子col-2的大小一致,因为轮播图片大小与父盒子们的大小一致,slider-img-box盒子里面包裹滚动条以及图片,在后面将图片以及滚动条设置为两个不同的盒子,注意:这个盒子定位属性设置为relative,目的是后面的图片和滚动条可以参照它做位移,但是也可以设置为absolute,因为后面的盒子的定位属性也是absolute,它们作位移是参照最近的父级定位盒子做位移,所以也可以,但是相对定位不脱表,这一点很重要,所以还是采用相对定位.
好了,现在我们着重介绍slider-img-box盒子的布局样式介绍:
整个轮播图的核心布局点
slider-img盒子里面包裹一个与它大小一样的a标签,a标签下面再包裹img标签,(相当于一张图片就是一个a标签)因为a是行内元素,但是slider-img的大小只能放一张图片,所以-----------------后面的所有图片都是叠加在第一张图片的下面的--------------------
现在是要滚动一次后面的图片要提到第一张来显示,那我们可以利用z-index的层级来控制那张图片该放到最前面来
第二: 这两个盒子的一个对应官方的轮播图,一个对应合作的轮播图,在两个盒子的外面单纯的设计一个slideTypeBd盒子目的只是为了让其把这两个sliderCon1与sliderCon2包裹起来,因为涉及到两个轮播图:我们只需要设置其中的一个盒子显示,另一个盒子隐藏;当鼠标点击切换时,再改变两者的显示模式就可以了.在sliderCon1(类名slider-img-box)盒子下面设计一个包图片的盒子slider-img,以及包裹轮播滚动条的slider-dot,在轮播滚动条这里在设计一个active类来改变鼠标移入时的样式.
第三: 做完这一步还有一个问题,就是所有图片都是显示的,那么图片从后一张提升到最前面显示,这之间图片之间的切换又是动画完成,这之间的过程渲染在页面就是到达时间后,原来第一张图片突然消失(层级降低了),后来的图片突然出现(层级变高),整个过程就变得很突兀,为了解决这种问题,我们利用opacity属性来解决,当层级是最高的时候,让其opcity为1,其余时候opcity都是0,同样用动画的效果来渲染到页面上,这样就可以解决刚才的突兀问题了.
总结:在布局时候,个人喜欢将所有的内容用div包起来,这样检查的时候,就可以直接去找我的DIV看是否有问题,一层一层的去分析,方便解决问题.
HTML代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="./test.css">
</head>
<body>
<div class="col-2">
<div class="sliders-cont">
<!-- 切换模块设计 -->
<div class="slide-type" id="slideType">
<a href="javascript:;" class="active">官方</a>
<a href="javascript:;">合作</a>
</div>
<div class="slideTypeBd">
<!-- 官方对应的轮播图 -->
<div id="sliderCon1" class="slider-img-box ishow">
<!-- 官方对应的图片 -->
<div id="bannerImgsliderCon1" class="slider-img">
<a target="_blank" href="#" style="opacity: 1; z-index: 10;">
<img alt="" src="./images/1new.jpg" width="470" height="355">
</a>
<a target="_blank" href="#" style="opacity: 0; z-index: 9;">
<img alt="" src="./images/2new.jpg" width="470" height="355">
</a>
<a target="_blank" href="#" style="opacity: 0; z-index: 9;">
<img alt="" src="./images/3new.jpg" width="470" height="355">
</a>
<a target="_blank" href="#" style="opacity: 0; z-index: 9;">
<img alt="" src="./images/4new.jpg" width="470" height="355">
</a>
<a target="_blank" href="#" style="opacity: 0; z-index: 9;">
<img alt="" src="./images/5new.jpg" width="470" height="355">
</a>
<a target="_blank" href="#" style="opacity: 0; z-index: 9;">
<img alt="" src="./images/6new.jpg" width="470" height="355">
</a>
</div>
<!-- 官方对应的滚动bar -->
<div class="slider-dot" id="bannerCtrlsliderCon1">
<a class="dot-item on" target="_blank" href="#">七夕 岛上大冒险!</a>
<a class="dot-item" target="_blank" href="#">每日福利重磅来袭</a>
<a class="dot-item" target="_blank" href="#">街霸同人有奖征集</a>
<a class="dot-item" target="_blank" href="#">新商品</a>
<a class="dot-item" target="_blank" href="#">回归计划</a>
<a class="dot-item" target="_blank" href="#">冒险不孤单:师徒活动</a>
</div>
</div>
<!-- 合作对应的轮播图 -->
<div id="sliderCon2" class="slider-img-box">
<!-- 合作对应的图片 -->
<div id="bannerImgsliderCon2" class="slider-img">
<a target="_blank" href="#" style="opacity: 1; z-index: 10;">
<img alt="" src="./images/21new.jpg" width="470" height="355">
</a>
<a target="_blank" href="#" style="opacity: 0; z-index: 9;">
<img alt="" src="./images/22new.jpg" width="470" height="355">
</a>
<a target="_blank" href="#" style="opacity: 0; z-index: 9;">
<img alt="" src="./images/23new.jpg" width="470" height="355">
</a>
<a target="_blank" href="#" style="opacity: 0; z-index: 9;">
<img alt="" src="./images/24new.jpg" width="470" height="355">
</a>
<a target="_blank" href="#" style="opacity: 0; z-index: 9;">
<img alt="" src="./images/25new.jpg" width="470" height="355">
</a>
</div>
<!-- 合作对应的滚动bar -->
<div class="slider-dot" id="bannerCtrlsliderCon2">
<a class="dot-item on" target="_blank" href="#">wegame</a>
<a class="dot-item" target="_blank" href="#">管家</a>
<a class="dot-item" target="_blank" href="#">QQ会员</a>
<a class="dot-item" target="_blank" href="#">QQ浏览器</a>
<a class="dot-item" target="_blank" href="#">QQ管家</a>
</div>
</div>
</div>
</div>
</div>
</body>
CSS代码:
a {
text-decoration: none;
}
.col-2 {
width: 470px;
height: 355px;
margin: 100px auto;
}
.sliders-cont {
/* 给父盒子一个相对定位(子绝父相) */
position: relative;
width: 100%;
height: 100%;
}
/* 官方合作切换模块样式设计*/
.slide-type {
position: absolute;
right: 0;
bottom: 0;
/* 提高盒子层级防止被其他定位盒子覆盖 */
z-index: 999;
}
.slide-type a {
float: left;
display: inline;
padding: 0 10px;
color: #fff;
height: 30px;
line-height: 30px;
background: #444;
}
/* 合作官方背景的变化 */
.slide-type a.active {
background: #0079fe;
}
/*整个图片和滚动条的大盒子设置显示为none*/
.slider-img-box {
display: none;
position: relative;
width: 470px;
height: 355px;
}
/*ishow用来设置图片和滚动条的大盒子的显示属性*/
.ishow {
display: block!important;
}
/*图片盒子*/
.slider-img {
width: 100%;
height: 100%;
position: absolute;
z-index: 1;
}
.slider-img a {
position: absolute;
width: 100%;
height: 100%;
/*让文字隐藏*/
overflow: hidden;
}
.slider-dot {
position: absolute;
bottom: 22px;
left: 48px;
z-index: 10;
}
.slider-dot a {
display: inline-block;
width: 13px;
height: 13px;
background: #474c72;
margin-right: 4px;
border-radius: 7px;
line-height: 100px;
/*让文字隐藏*/
overflow: hidden;
}
/*滚动条滚动到下一页的样式改变属性*/
.slider-dot .on {
width: 32px;
background: #f5a700;
}
JS交互的问题:
一 事件的绑定:
因为在有的时候,我们不便触发移入事件,所以用到事件的绑定.这里就是因为在定时器里,不能添加移入事件,主要原因是我们并不知道定时器走到哪里了,比如:定时器每隔两秒钟执行一次,那么我们非常不清楚这两秒的间隔出现在哪个时间段.所以直接绑定到移入事件,由程序为我们去执行.
objTime.timeID1 = setInterval(function(){
idx.idxCon1++;
//第一个图片的边界检测,当图片是最大值的时候,让其值变为第一个
if(idx.idxCon1 > 5) {
idx.idxCon1 = 0;
}
//给滚动条绑定它自己的鼠标移入事件,这样定时器到来,执行的就是滚动条移入的事件
$('#bannerCtrlsliderCon1 .dot-item').eq(idx.idxCon1).trigger("mouseenter");
},1000);
三:阻止事件的冒泡:
事件冒泡的原因:当为子盒子和父盒子的注册同名事件时,触发子盒子的同名事件,父盒子的同名事件也会被触发,现在因为我们要给整个盒子注册一个移入事件(mouseenter),但是对于我们的滚动条(dot-item)也有相同的事件(mouseenter),所以为了防止事件触发我们要阻止事件的触发,jQuery提供的阻止事件件冒泡方法:event.stopPropagation() 阻止事件冒泡行为
//第一个图片
$('#bannerCtrlsliderCon1 .dot-item').on('mouseenter',function(e){
//当滚动条被鼠标移入时添加on的样式
$(this).addClass('on').siblings('a').removeClass('on');
idx.idxCon1 = $(this).index(); // 获取当前的索引号
//2.stop(参数1,参数2);
//参数1:是否清除队列
//参数2:是否跳转到最终效果
//让图片的动画渲染到页面上 $('#bannerImgsliderCon1').find('a').eq(idx.idxCon1).stop(true, false).animate({
'opacity': '1',
'z-index': '10'
}, 500, 'swing').siblings('a').css({
'opacity': '0',
'z-index': '9'
});
//阻止冒泡 阻止它的事件影响到父盒子的同名事件
e.stopPropagation();
});
//子盒子滚动条的最大父盒子拥有相同的事件mouseenter,
//这里的作用是鼠标移入关闭定时器,如果不阻止子盒子的事件冒泡,
//那么只要定时器一到,滚动条的移入事件就会被触发,子盒子的事件被触发,
//那么父盒子的移入事件,计时器被清空,也会被触发,图片滚动执行一次
//再也不会自动播放了
$('#sliderCon1').on('mouseenter',function(){
clearInterval(objTime.timeID1);
});
三.最后鼠标移出的时候,开启定时器.注意这里的定时器ID要与我清楚定时器的ID一致
//做一个鼠标移入的停止自动播放
$('#sliderCon1').on('mouseenter',function(){
//注意与清楚定时器的ID保持一致
clearInterval(objTime.timeID1);
});
jQuery代码:
<script src="jquery-1.12.4.js"></script>
<script>
$(function(){
//切换官方与合作的js设计
$('#slideType').find('a').on('click',function(){
//改变背景颜色
$(this).addClass('active').siblings('a').removeClass('active');
//改变显示模式的转换
var idx = $(this).index(); //获取索引
$('.slider-img-box').eq(idx).addClass('ishow').siblings('.slider-img-box').removeClass('ishow');
})
//轮播图的设计
var idx = {
idxCon1 : 0,
idxCon2 : 0
};
var objTime = {
timeID1 : null,
timeID2 : null
}
//自动播放的效果
//两个图片用同一个定时器
objTime.timeID1 = setInterval(function(){
//第一个图片的
idx.idxCon1++;
if(idx.idxCon1 > 5) {
idx.idxCon1 = 0;
}
$('#bannerCtrlsliderCon1 .dot-item').eq(idx.idxCon1).trigger("mouseenter");
},1000);
objTime.timeID2 = setInterval(function(){
//第二个图片
idx.idxCon2++;
if(idx.idxCon2 > 4) {
idx.idxCon2 = 0;
}
$('#bannerCtrlsliderCon2 .dot-item').eq(idx.idxCon2).trigger("mouseenter");
},1000);
//第一个图片
$('#bannerCtrlsliderCon1 .dot-item').on('mouseenter',function(e){
$(this).addClass('on').siblings('a').removeClass('on');
idx.idxCon1 = $(this).index(); // 获取当前的索引号
//2.stop(参数1,参数2);
//参数1:是否清除队列
//参数2:是否跳转到最终效果
$('#bannerImgsliderCon1').find('a').eq(idx.idxCon1).stop(true, false).animate({
'opacity': '1',
'z-index': '10'
}, 500, 'swing').siblings('a').css({
'opacity': '0',
'z-index': '9'
});
//阻止冒泡
e.stopPropagation();
});
//第二个图片的轮播效果
$('#bannerCtrlsliderCon2 .dot-item').on('mouseenter',function(e){
$(this).addClass('on').siblings('a').removeClass('on');
idx.idxCon2 = $(this).index(); // 获取当前的索引号
//2.stop(参数1,参数2);
//参数1:是否清除队列
//参数2:是否跳转到最终效果
$('#bannerImgsliderCon2').find('a').eq(idx.idxCon2).stop(true, false).animate({
'opacity': '1',
'z-index': '10'
}, 500, 'swing').siblings('a').css({
'opacity': '0',
'z-index': '9'
});
//阻止冒泡
e.stopPropagation();
});
//做一个鼠标移入的停止自动播放
$('#sliderCon1').on('mouseenter',function(){
clearInterval(objTime.timeID1);
});
//鼠标移出开启自动播放
$('#sliderCon1').on('mouseleave',function(e){
objTime.timeID1 = setInterval(function(){
//第一个图片的
idx.idxCon1++;
if(idx.idxCon1 > 5) {
idx.idxCon1 = 0;
}
$('#bannerCtrlsliderCon1 .dot-item').eq(idx.idxCon1).trigger("mouseenter");
},1000);
//阻止冒泡
e.stopPropagation();
});
$('#sliderCon2').on('mouseenter',function(){
clearInterval(objTime.timeID2);
});
$('#sliderCon2').on('mouseleave',function(e){
//第二个图片
objTime.timeID2 = setInterval(function(){
//第一个图片的
idx.idxCon2++;
if(idx.idxCon2 > 4) {
idx.idxCon2 = 0;
}
$('#bannerCtrlsliderCon2 .dot-item').eq(idx.idxCon2).trigger("mouseenter");
},1000);
//阻止冒泡
e.stopPropagation();
});
})
</script>
上面的代码:是为了让我们理解其中原理写的,比较冗余,现在进行封装处理,精简代码: