分析
目录
编译并压缩less(需要先npm安装less)
banner.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<!--development-->
<!--<link rel="stylesheet/less" href="css/banner.less">
<script src="js/less-2.5.3.min.js"></script>-->
<!--production-->
<link rel="stylesheet" href="css/banner.min.css">
</head>
<body>
<div class="container" id="container">
<!--WRAPPER:控制轮播图切换的区域-->
<ul class="wrapper">
<!--<li class="slide">
<img src="" data-img="img/banner1.jpg" alt="">
</li>-->
</ul>
<!--FOCUS:控制焦点-->
<ul class="focusBox clearfix">
<!--<li class="select"></li>
<li></li>
<li></li>
<li class="last"></li>-->
</ul>
<!--ARROW:控制切换的箭头-->
<a href="javascript:;" class="arrow arrowLeft"></a>
<a href="javascript:;" class="arrow arrowRight"></a>
</div>
<!--IMPORT JS-->
<script src="js/utils.min.js"></script>
<script src="js/animate.min.js"></script>
<script src="js/banner.js"></script>
</body>
</html>
复制代码
banner.less
@import "reset";
/*--BANNER--*/
.container {
position: relative;
margin: 20px auto;
width: 1000px;
height: 300px;
overflow: hidden;
text-align: center;
.wrapper {
position: relative;
height: 300px;
background: url("../img/default.gif") no-repeat center center #EEE;
.slide {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
//=>init style
opacity: 0;
filter: alpha(opacity=0);
z-index: 0;
img {
display: none;
width: 100%;
height: 100%;
}
}
}
.focusBox {
position: relative;
top: -40px;
z-index: 999;
display: inline-block;
padding: 4px 8px;
height: 12px;
background: rgba(0, 0, 0, .2);
border-radius: 12px;
li {
float: left;
margin-right: 10px;
width: 12px;
height: 12px;
border-radius: 50%;
background: #FFF;
cursor: pointer;
&.last {
margin-right: 0;
}
&.select {
background: #DB192A;
}
}
}
.arrow {
display: none;
position: absolute;
top: 50%;
z-index: 999;
margin-top: -30px;
width: 30px;
height: 60px;
background: url("../img/pre.png") no-repeat;
opacity: 0.3;
filter: alpha(opacity=30);
&:hover {
opacity: 1;
filter: alpha(opacity=100);
}
&.arrowLeft {
left: 0;
background-position: 0 0;
}
&.arrowRight {
right: 0;
background-position: -48px 0;
}
}
}
复制代码
reset.less
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, button, input, textarea, th, td {
margin: 0;
padding: 0
}
body {
font-size: 12px;
font-style: normal;
font-family: "\5FAE\8F6F\96C5\9ED1", Helvetica, sans-serif
}
small {
font-size: 12px
}
h1 {
font-size: 18px
}
h2 {
font-size: 16px
}
h3 {
font-size: 14px
}
h4, h5, h6 {
font-size: 100%
}
ul, ol {
list-style: none
}
a {
text-decoration: none;
background-color: transparent
}
a:hover, a:active {
outline-width: 0;
text-decoration: none
}
table {
border-collapse: collapse;
border-spacing: 0
}
hr {
border: 0;
height: 1px
}
img {
border-style: none
}
img:not([src]) {
display: none
}
svg:not(:root) {
overflow: hidden
}
html {
-webkit-touch-callout: none;
-webkit-text-size-adjust: 100%
}
input, textarea, button, a {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0)
}
article, aside, details, figcaption, figure, footer, header, main, menu, nav, section, summary {
display: block
}
audio, canvas, progress, video {
display: inline-block
}
audio:not([controls]), video:not([controls]) {
display: none;
height: 0
}
progress {
vertical-align: baseline
}
mark {
background-color: #ff0;
color: #000
}
sub, sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline
}
sub {
bottom: -0.25em
}
sup {
top: -0.5em
}
button, input, select, textarea {
font-size: 100%;
outline: 0
}
button, input {
overflow: visible
}
button, select {
text-transform: none
}
textarea {
overflow: auto
}
button, html [type="button"], [type="reset"], [type="submit"] {
-webkit-appearance: button
}
button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0
}
button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText
}
[type="checkbox"], [type="radio"] {
box-sizing: border-box;
padding: 0
}
[type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button {
height: auto
}
[type="search"] {
-webkit-appearance: textfield;
outline-offset: -2px
}
[type="search"]::-webkit-search-cancel-button, [type="search"]::-webkit-search-decoration {
-webkit-appearance: none
}
::-webkit-input-placeholder {
color: inherit;
opacity: .54
}
::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit
}
.clearfix:after {
display: block;
height: 0;
content: "";
clear: both
}
复制代码
banner.json
[
{
"id": 1,
"img": "img/banner1.jpg",
"desc": "海,你好",
"link": "http://www.baidu.cn/"
},
{
"id": 2,
"img": "img/banner2.jpg",
"desc": "梦想起飞",
"link": "http://www.baidu.cn/"
},
{
"id": 3,
"img": "img/banner3.jpg",
"desc": "把握未来,掌握先机",
"link": "http://www.baidu.cn/"
},
{
"id": 4,
"img": "img/banner4.jpg",
"desc": "好好学习",
"link": "http://www.baidu.cn/"
}
]
复制代码
banner.js
// var bannerRender = (function () {
// return {
// init: function () {
// }
// }
// })();
// bannerRender.init();
var bannerRender = (function () {
var container = document.getElementById('container'),
wrapper = utils.getElementsByClassName('wrapper', container)[0],
focusBox = utils.getElementsByClassName('focusBox', container)[0],
arrow = utils.children(container, 'a'),
arrowLeft = arrow[0],
arrowRight = arrow[1];
var bannerData = null,
wrapperList = null,
focusList = null,
wrapperImgList = null;
//=>1、ajax获取数据
function queryData() {
var xhr = new XMLHttpRequest();
xhr.open('get', 'json/banner.json', false);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
bannerData = utils.toJSON(xhr.responseText);
}
};
xhr.send(null);
}
//=>2、绑定数据
function bindData() {
if (!bannerData) return;
var str = ``,
strFocus = ``;
for (var i = 0; i < bannerData.length; i++) {
var item = bannerData[i];
str += `<li class="slide">
<img src="" data-img="${item.img}" alt="">
</li>`;
strFocus += `<li class="${i === bannerData.length - 1 ? 'last' : ''}"></li>`;
}
wrapper.innerHTML = str;
focusBox.innerHTML = strFocus;
//=>5、数据绑定完需要获取所有的LI以及IMG,后面会用到
wrapperList = wrapper.getElementsByTagName('li');
focusList = focusBox.getElementsByTagName('li');
wrapperImgList = wrapper.getElementsByTagName('img');
}
//=>6、设置默认展示
function initDefault(index) {
index = index || 0;
utils.css(wrapperList[index], {
opacity: 1,
zIndex: 1
});
focusList[index].className += ' select';//=>一定是加等于(因为部分LI有自己的原有样式)
}
//=>8、图片延迟加载
function computed() {
if (!wrapperImgList) return;
for (var i = 0; i < wrapperImgList.length; i++) {
var curImg = wrapperImgList[i];
if (curImg.isLoad) continue;
lazyImg(curImg);
}
}
function lazyImg(curImg) {
curImg.isLoad = true;
var tempImg = new Image;//创建一个临时
tempImg.onload = function () {
curImg.src = this.src;
curImg.style.display = 'block';
tempImg = null;
};
tempImg.src = curImg.getAttribute('data-img');
}
//=>10、实现轮播图的自动切换
var step = 0,//->记录当前展示的是第几个SLIDE(索引)
prevStep = 0,//->记录上一个展示的SLIDE索引
autoInterval = 2000,//->自动切换的时间因子
autoTimer = null,//->自动切换的定时器
count = 0;//->总共的SLIDE数量
function autoMove() {
step++;
if (step === count) {
step = 0;
}
change();
}
//=>轮播图公共切换方法
function change() {
if (step === prevStep) return;
var curSlide = wrapperList[step],
preSlide = wrapperList[prevStep];
//->当前展示的SLIDE层级变为1 & 上一个展示的SLIDE层级变为0
utils.css(curSlide, 'zIndex', 1);
utils.css(preSlide, 'zIndex', 0);
//->让当前展示的SLIDE透明度从0~1(动画)
animate({
curEle: curSlide,
target: {opacity: 1},
duration: 200,
callBack: function () {
//=>上一个SLIDE隐藏(透明度为0)
utils.css(preSlide, 'opacity', 0);
}
});
//->当前展示的这一个SLIDE就是下一次切换的上一次SLIDE
prevStep = step;
//=>14、切换的时候要执行selectFocus让其焦点对齐
selectFocus();
}
//=>13、焦点对齐的方法(这里用的是循环所有的焦点给当前索引加样式);还有种方式:可以用清除上一个焦点样式给当前焦点加样式
function selectFocus() {
for (var i = 0; i < focusList.length; i++) {
var item = focusList[i];
if (i === focusList.length - 1) {//最后一个焦点有last做特殊处理
item.className = i === step ? 'last select' : 'last';
continue;
}
item.className = i === step ? 'select' : '';
}
}
//=>15、鼠标划入划出BANNER区域控制自动切换的暂停和开始 用onmouseout和onmouseover有问题,后面会写
function bindMouseEvent() {
container.onmouseenter = function () {
clearInterval(autoTimer);
arrowLeft.style.display = arrowRight.style.display = 'block';//鼠标滑进来左右箭头显示
};
container.onmouseleave = function () {
autoTimer = setInterval(autoMove, autoInterval);
arrowLeft.style.display = arrowRight.style.display = 'none';//鼠标离开左右箭头隐藏
};
}
//=>16、滑过焦点实现切换
function bindFocus() {
for (var i = 0; i < focusList.length; i++) {
focusList[i].myIndex = i;
focusList[i].onmouseenter = function () {
step = this.myIndex;
change();
}
}
}
//=>17、点击左右按钮切换
function bindArrow() {
arrowLeft.onclick = function () {
step--;
if (step < 0) {
step = count - 1;
}
change();
};
arrowRight.onclick = autoMove;
}
return {
init: function () {
// 9、执行computed延迟加载
// setTimeout(computed,500);//可以看延迟加载效果
window.onload = computed;//=>当页面加载完成后做图片的延迟加载(放在上面也无所谓,因为事件绑定是异步编程:写在上面,也是需要等下面的代码都加载完成,页面才加载完成,才会触发LOAD事件)
// 3、执行queryData()
queryData();
// 4、执行bindData()
bindData();
// 7、执行
initDefault(step);
//=>实现轮播图的切换
count = bannerData.length;//11、获取总共的SLIDE数量
autoTimer = setInterval(autoMove, autoInterval);//12、执行autoMove
//=>18、其它切换方式
bindMouseEvent();
bindFocus();
bindArrow();
}
}
})();
bannerRender.init();
复制代码
其余文件同之前封装的库(动画库animate和dom库utils)