封裝banner外掛(完整版)
左右運動版輪播圖
-
自動切換並且實現無縫斜街
-
點選焦點切換
-
點選左右切換
-
封裝輪播圖外掛
-
...
window.onload=function(){}容易被覆蓋掉的解決方案
什麼時候執行延遲載入:當頁面載入成功才執行延遲載入。
window.onload=function(){};但是window.onload在當前頁面只能執行一次,所以容易被覆蓋掉,最好不用
所以可以用window.addEventListener('load');但是不相容
所以這裡用定時器setTimeout();當整個js同步都執行完後(頁面都載入完後)才會執行這個非同步
所以很多時候都用定時器setTimeout()來代替window.onload
目錄
思路
banner.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<!--<link rel="stylesheet/less" href="css/banner.less">
<script src="js/less-2.5.3.min.js"></script>-->
<link rel="stylesheet" href="css/banner.min.css">
</head>
<body>
<!--BANNER-->
<div class="container" id="container">
<!--WRAPPER-->
<ul class="wrapper clearfix">
<!--<li class="slide">
<a href="#">
<img src="img/banner1.jpg" alt="">
</a>
</li>-->
</ul>
<!--FOCUS-BOX-->
<ul class="focusBox clearfix">
<!--<li class="select"></li>
<li></li>-->
</ul>
<!--ARROW-->
<a href="javascript:;" class="arrow arrowLeft"></a>
<a href="javascript:;" class="arrow arrowRight"></a>
</div>
<div class="container" id="container2">
<!--WRAPPER-->
<ul class="wrapper clearfix">
</ul>
<!--FOCUS-BOX-->
<ul class="focusBox clearfix">
<!--<li class="select"></li>
<li></li>-->
</ul>
</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";
.container {
@W: 1000px;
@H: 300px;
position: relative;
margin: 20px auto;
width: @W;
height: @H;
text-align: center;
overflow: hidden;
background: url("../img/default.gif") no-repeat center center #EEE;
.wrapper {
position: absolute;
top: 0;
left: 0;
width: unit(unit(@W,px)*10, px); //=>需要在JS中根據獲取的資料動態設定寬度
height: @H;
.slide {
float: left;
width: @W;
height: @H;
a {
display: block;
width: @W;
height: @H;
img {
display: none;
width: @W;
height: @H;
opacity: 0;
filter: alpha(opacity=0);
}
}
}
}
.focusBox {
display: inline-block;
position: relative;
top: unit(unit(@H,px)-30, px);
z-index: 999;
padding: 4px;
background: #999;
background: rgba(0, 0, 0, .5);
border-radius: 20px;
li {
float: left;
margin: 0 4px;
width: 12px;
height: 12px;
background: #FFF;
border-radius: 50%;
cursor: pointer;
&.select {
background: #E01D20;
}
}
}
.arrow {
display: none;
position: absolute;
top: 50%;
margin-top: -22.5px;
width: 28px;
height: 45px;
background: url("../img/pre.png") no-repeat;
opacity: 0.5;
filter: alpha(opacity=50);
&.arrowLeft {
left: 0;
}
&.arrowRight {
right: 0;
background-position: -50px 0;
}
&:hover {
opacity: 1;
filter: alpha(opacity=100);
}
}
}
複製程式碼
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.js
~function (options) {
var container = document.getElementById('container'),
containerChild = utils.children(container),
wrapper = containerChild[0],
focusBox = containerChild[1],
arrowLeft = containerChild[2],
arrowRight = containerChild[3];
var slideList = null,
imgList = null,
focusList = null,
bannerData = null,
containerWidth = container.clientWidth;
//=>INIT PARAMETERS 預設設定
var _default = {
initIndex: 0,
autoInterval: 2000
};
//遍歷options替換預設設定
for (var key in options) {
if (options.hasOwnProperty(key)) {
_default[key] = options[key];
}
}
var initIndex = _default.initIndex,
autoInterval = _default.autoInterval;
//=>GET DATA & BIND DATA
~function () {
//->AJAX GET DATA 獲取資料
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);
//->BIND DATA 繫結資料
var str = ``,
strFocus = ``;
for (var i = 0; i < bannerData.length; i++) {
var item = bannerData[i];
str += `<li class="slide">
<a href="${item.link}">
<img src="" data-img="${item.img}" alt="${item.desc}">
</a>
</li>`;
strFocus += `<li></li>`;
}
wrapper.innerHTML = str;
focusBox.innerHTML = strFocus;
//->GET ELEMENT LIST
slideList = wrapper.getElementsByTagName('li');
imgList = wrapper.getElementsByTagName('img');
focusList = focusBox.getElementsByTagName('li');
//=>CLONE 克隆第一張到末尾 cloneNode(true)深度克隆
wrapper.appendChild(slideList[0].cloneNode(true));
//->COMPUTED WRAPPER WIDTH
utils.css(wrapper, 'width', (bannerData.length + 1) * containerWidth);
}();
//=>INIT SHOW & LAZY IMG
~function () {
//->FOCUS DEFAULT SHOW
for (var i = 0; i < focusList.length; i++) {
focusList[i].className = i === initIndex ? 'select' : null;
}
//->WRAPPER DEFAULT SHOW
utils.css(wrapper, 'left', -containerWidth * initIndex);
//->LAZY IMG 懶載入
// 什麼時候執行延遲載入:當頁面載入成功才執行延遲載入
// window.onload=function(){};但是window.onload在當前頁面只能執行一次,所以容易被覆蓋掉,最好不用。
// 所以可以用window.addEventListener('load');但是不相容
// 所以這裡用定時器setTimeout();當整個js同步都執行完後(頁面都載入完後)才會執行這個非同步,所以這裡500ms可以寫成0ms也行
// 所以很多時候都用定時器setTimeout()來代替window.onload
var timer = setTimeout(function () {
for (var k = 0; k < imgList.length; k++) {
lazyImg(imgList[k]);
}
clearTimeout(timer);
}, 500);
function lazyImg(curImg) {
var tempImg = new Image;
tempImg.onload = function () {
curImg.src = this.src;
curImg.style.display = 'block';
animate({
curEle: curImg,
target: {opacity: 1},
duration: 200
});
tempImg = null;
};
tempImg.src = curImg.getAttribute('data-img');
}
}();
//=>AUTO CHANGE 自動切換 當運動到最後一張,讓wrapper瞬移到第一張,並且讓initIndex = 1,再執行動畫就從第二張開始
var autoTimer = null;
autoTimer = setInterval(autoMove, autoInterval);
function autoMove() {
initIndex++;
if (initIndex === bannerData.length + 1) {
utils.css(wrapper, 'left', 0);
initIndex = 1;
}
change();
}
//=>MOUSE EVENT
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';
};
//=>BIND FOCUS EVENT
~function () {
for (var i = 0; i < focusList.length; i++) {
focusList[i].myIndex = i;
focusList[i].onclick = function () {
initIndex = this.myIndex;
change();
}
}
}();
//=>BIND ARROW EVENT
~function () {
arrowRight.onclick = autoMove;
arrowLeft.onclick = function () {
initIndex--;
if (initIndex === -1) {
//->RUN TO CLONE ELEMENT
utils.css(wrapper, 'left', -bannerData.length * containerWidth);
initIndex = bannerData.length - 1;
}
change();
}
}();
//=>CHANGE
function change() {
animate({
curEle: wrapper,
target: {left: -initIndex * containerWidth},
duration: 300
});
//->CHANGE FOCUS
var tempIndex = initIndex;
tempIndex === bannerData.length ? tempIndex = 0 : null;
for (var i = 0; i < focusList.length; i++) {
focusList[i].className = i === tempIndex ? 'select' : null;
}
}
}();
複製程式碼
banner.json
複製程式碼
[
{
"id": 1,
"img": "img/banner1.jpg",
"desc": "推薦機會",
"link": "http://www.baidu.com/"
},
{
"id": 2,
"img": "img/banner2.jpg",
"desc": "夢想起飛",
"link": "http://www.baidu.com/"
},
{
"id": 3,
"img": "img/banner3.jpg",
"desc": "把握未來",
"link": "http://www.baidu.com/"
},
{
"id": 4,
"img": "img/banner4.jpg",
"desc": "先學習",
"link": "http://www.baidu.com/"
}
]
複製程式碼
封裝banner外掛(封裝外掛的基本思路)
外掛思想:功能越強大越好
首先理解jq中最難理解的部分:
如何讓一個函式執行,建立一個屬於自己函式和這個類的例項
~function () {
function BannerPlugin(options) {//建構函式建立一個類 options配置引數
return new BannerPlugin.fn.init(options);
}
BannerPlugin.fn = BannerPlugin.prototype = {};
var init = BannerPlugin.fn.init = function (options) {
};
init.prototype = BannerPlugin.prototype;
}();
//--------------------------以上可以簡寫成以下-----------------------------------------
// 封裝外掛直接用建構函式模式 先寫一個自執行函式~function (){},
// 在裡面建立一個類BannerPlugin(),
// 執行BannerPlugin()會配置很多引數,很多引數用options來配置
~function () {
function BannerPlugin(options) {
// 執行BannerPlugin這個方法建立的是init對應函式的例項,
// 但是會用到BannerPlugin.prototype原型上的方法,所以
// BannerPlugin.prototype.init.prototype = BannerPlugin.prototype;
return new BannerPlugin.prototype.init(options);
}
BannerPlugin.prototype = {
//為了保證完建構函式完整性,constructor:BannerPlugin
//見JS中的閉包及物件導向程式設計 — 2、物件導向程式設計詳解 19-2重新構造原型(最常用))
constructor:BannerPlugin,
init:function (options) { // 建立的是init時有個形參options,這裡需要通過options接收
// 這裡的this也可以呼叫BannerPlugin原型上的方法 看到20:20
}
};
// 讓INIT的原型指向BANNER-PLUGIN的原型,目的:當執行BANNER-PLUGIN方法的時候建立出來的依然是BANNER-PLUGIN類的例項
BannerPlugin.prototype.init.prototype = BannerPlugin.prototype;
console.dir(BannerPlugin({}));//直接執行BannerPlugin()先建立init例項,由init例項再變成BannerPlugin例項,不用再通過newBannerPlugin()去建立BannerPlugin例項
window.$banner = window.BannerPlugin = BannerPlugin;//暴露BannerPlugin
}();
BannerPlugin({});
$banner({});
複製程式碼
圖解:
首先一個類BannerPlugin(),有屬性prototype;
BannerPlugin.prototype開闢一個新堆記憶體;(自己開闢的新堆記憶體沒有constructor, 為了保證完建構函式完整性,constructor:BannerPlugin 見JS中的閉包及物件導向程式設計 — 2、物件導向程式設計詳解 19-2重新構造原型(最常用));
原型prototype的_proto_都指向Object的原型
BannerPlugin.prototype裡面有個init方法,方法又是一個堆記憶體BannerPlugin.prototype.init (BannerPlugin.prototype.init又是一個函式資料型別,有屬性prototype)
BannerPlugin.prototype.init.prototype = BannerPlugin.prototype:讓init的原型指向BannerPlugin的原型, 目的:當執行BannerPlugin方法的時候會通過return new BannerPlugin.prototype.init(options)建立init這個方法 的例項(init的例項),init的例項有_proto_指向所屬類的原型,最終還是指向了BannerPlugin的原型,所以創 建的init依然是BannerPlugin類的例項
為什麼要這麼做呢,為什麼不直接建立BannerPlugin這個類的例項呢?
這麼做有個好處=>直接執行BannerPlugin({})返回的例項就是BannerPlugin()這個類的例項,不再需要通過new BannerPlugin()去建立這個類的例項, 而是通過先建立init例項,由init例項再變成BannerPlugin例項(通過console.dir(BannerPlugin({}))列印出來看是個死迴圈巢狀, 在原型裡面是沒有這個概念的,因為constructor建構函式雖然指向BannerPlugin,但是和普通類還是有所區別,並不會形成死迴圈)如圖:
這個怎麼去找上級?
init例項裡面沒有通過_proto_找到BannerPlugin.prototype,BannerPlugin.prototype沒有再通過BannerPlugin.prototype.proto 找到Object.prototype。(這裡上級查詢不會去找BannerPlugin.prototype裡的constructor,這個不會形成死迴圈)
封裝外掛
看懂了jq最難理解的部分,接下來一步步寫外掛
plugin-banner.js參照banner.js封裝成外掛的,對應banner.js看(方法裡面的程式碼都是複製貼上,改變引數,涉及utils的用原生,this...),注意this,並且把很多屬性方法寫在私有屬性上就可以了。
plugin-banner.js
/*
* 分析我們需要支援的部分:
* [基礎]
* 資料動態繫結的地址是不同的 (url)
* 切換速度 (speed:300)
* 預設展示第幾張 (initIndex:0)
* 延遲多久進行圖片懶載入 (lazyImgTime:500)
*
* [自動切換]
* 是否支援自動切換 (needAutoChange:true)
* 自動切換的間隔時間 (autoInterval:2000)
*
* [焦點]
* 是否顯示焦點 (isFocusShow:true)
* 是否需要通過焦點切換 (needFocusChange:true)
* 什麼樣的事件控制焦點切換 (focusEvent:click)
*
* [左右切換]
* 是否支援左右切換 (isArrowShow:true)
*/
~function () {
function BannerPlugin(options) {
return new BannerPlugin.prototype.init(options);
}
BannerPlugin.prototype = {
constructor: BannerPlugin,
//=>1、宣告可擴充引數的預設值,並且讓傳遞引數的值OPTIONS替換原有的預設值(把需要用的引數擴充套件到例項的私有屬性上)
initDefault: function (options) {
var _default = {
container: null,
url: null,
initIndex: 0,
speed: 300,
lazyImgTime: 500,
needAutoChange: true,
autoInterval: 2000,
isFocusShow: true,
needFocusChange: true,
focusEvent: 'click',
isArrowShow: true
};
//=>迴圈options替換預設值
for (var key in options) {
if (options.hasOwnProperty(key)) {
_default[key] = options[key];
}
}
//=>把_DEFAULT中的每一項遍歷到THIS例項上(寫到私有屬性上)後銷燬_default
for (key in _default) {
if (_default.hasOwnProperty(key)) {
this[key] = _default[key];
}
}
_default = null;
},
//=>3、AJAX資料繫結(複製banner.js中的程式碼邏輯,修改url,把bannerData擴充到例項上,獲取元素和克隆)
// 這裡ajax用的同步程式設計,專案中用非同步(需要用到promise),(所以這個封裝是個入門的外掛,不建議專案中使用,同步會有問題)
queryData: function () {
var xhr = new XMLHttpRequest(),
bannerData = null;
xhr.open('GET', this.url, false);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
bannerData = JSON.parse(xhr.responseText);
}
};
xhr.send(null);
//=>擴充到例項上,方便以後再其它方法中使用
this.bannerData = bannerData;
},
bindData: function () {
var str = ``,
strFocus = ``;
for (var i = 0; i < this.bannerData.length; i++) {
var item = this.bannerData[i];
str += `<li class="slide">
<a href="${item.link}">
<img src="" data-img="${item.img}" alt="${item.desc}">
</a>
</li>`;
strFocus += `<li data-index="${i}"></li>`;
}
this.wrapper.innerHTML = str;
this.isFocusShow ? this.focusBox.innerHTML = strFocus : null;
//=>其它事情
this.slideList = this.wrapper.getElementsByTagName('li');
this.imgList = this.wrapper.getElementsByTagName('img');
this.isFocusShow ? this.focusList = this.focusBox.getElementsByTagName('li') : null;
//=>克隆第一張到末尾
this.wrapper.appendChild(this.slideList[0].cloneNode(true));
this.wrapper.style.width = (this.bannerData.length + 1) * this.containerWidth;
},
//=>6、圖片延遲載入
lazyImg: function () {
var _this = this;
var timer = setTimeout(function () {//setTimeout中的this是window
[].forEach.call(_this.imgList, function (curImg) {
var tempImg = new Image;
tempImg.onload = function () {
curImg.src = this.src;
curImg.style.display = 'block';
animate({
curEle: curImg,
target: {opacity: 1},
duration: 200
});
tempImg = null;
};
tempImg.src = curImg.getAttribute('data-img');
});
clearTimeout(timer);
}, this.lazyImgTime);
},
//=>8、預設展示
showInit: function () {
var _this = this;
if (_this.isFocusShow) {
[].forEach.call(_this.focusList, function (item, index) {
item.className = index === _this.initIndex ? 'select' : null;
});
}
_this.wrapper.style.left = -_this.containerWidth * _this.initIndex + 'px';
},
//=>10、自動切換
change: function () {
animate({
curEle: this.wrapper,
target: {left: -this.initIndex * this.containerWidth},
duration: this.speed
});
//->CHANGE FOCUS
if (this.isFocusShow) {
var tempIndex = this.initIndex;
tempIndex === this.bannerData.length ? tempIndex = 0 : null;
[].forEach.call(this.focusList, function (item, index) {
item.className = index === tempIndex ? 'select' : null;
});
}
},
autoMove: function () {
this.initIndex++;
if (this.initIndex === this.bannerData.length + 1) {
this.wrapper.style.left = 0;
this.initIndex = 1;
}
this.change();
},
//=>12、其它切換方式
mouseEvent: function () {
var _this = this;
_this.container.onmouseenter = function () {
_this.needAutoChange ? clearInterval(_this.autoTimer) : null;
_this.isArrowShow ? _this.arrowLeft.style.display = _this.arrowRight.style.display = 'block' : null;
};
_this.container.onmouseleave = function () {
_this.needAutoChange ? _this.autoTimer = setInterval(_this.autoMove.bind(_this), _this.autoInterval) : null;
_this.isArrowShow ? _this.arrowLeft.style.display = _this.arrowRight.style.display = 'none' : null;
};
},
arrowEvent: function () {
var _this = this;
if (!_this.isArrowShow) return;
_this.arrowRight.onclick = _this.autoMove.bind(_this);//保證_this.autoMove方法中的this是例項
_this.arrowLeft.onclick = function () {
_this.initIndex--;
if (_this.initIndex === -1) {
_this.wrapper.style.left = -_this.bannerData.length * _this.containerWidth + 'px';
_this.initIndex = _this.bannerData.length - 1;
}
_this.change();
}
},
eventFocus: function () {
var _this = this;
if (!_this.isFocusShow) return;
if (!_this.needFocusChange) return;
[].forEach.call(_this.focusList, function (item, index) {
item['on' + _this.focusEvent] = function () {
_this.initIndex = index;
_this.change();
}
});
},
delegateEvent: function () {
var _this = this;
_this.container.onclick = function (e) {
e = e || window.event;
var target = e.target || e.srcElement,
targetParent = target.parentNode;
//=>焦點事件源
if (/(^| +)focusBox( +|$)/i.test(targetParent.className)) {
_this.initIndex = parseFloat(target.getAttribute('data-index'));
_this.change();
return;
}
//=>左右切換事件源
if (/(^| +)arrow( +|$)/i.test(target.className)) {
if (target.className.indexOf('arrowRight') > -1) {
_this.autoMove();
return;
}
_this.initIndex--;
if (_this.initIndex === -1) {
_this.wrapper.style.left = -_this.bannerData.length * _this.containerWidth + 'px';
_this.initIndex = _this.bannerData.length - 1;
}
_this.change();
}
};
},
init: function (options) {
//=>2、引數初始化
this.initDefault(options);
//=>4、獲取需要使用的到的元素
// var container = document.getElementById('container'),
// containerChild = utils.children(container),
// wrapper = containerChild[0],
// focusBox = containerChild[1],
// arrowLeft = containerChild[2],
// arrowRight = containerChild[3];
// var slideList = null,
// imgList = null,
// focusList = null,
// bannerData = null,
// containerWidth = container.clientWidth;
// 以上可以寫成
// this.wrapper = this.container.querySelector('.wrapper');
// this.focusBox = this.container.querySelector('.focusBox');
// this.arrowLeft = this.container.querySelector('.arrowLeft');
// this.arrowRight = this.container.querySelector('.arrowRight');
// this.containerWidth = this.container.clientWidth;
// var slideList = null,
// imgList = null,
// focusList = null;
// 以上可以寫成
var _this = this;
['wrapper', 'focusBox', 'arrowLeft', 'arrowRight'].forEach(function (item, index) {
_this[item] = _this.container.querySelector('.' + item);
});
this.containerWidth = this.container.clientWidth;
//=>5、資料繫結
this.queryData();
this.bindData();
//=>7、圖片延遲載入
this.lazyImg();
//=>9、預設展示
this.showInit();
//=>11、自動切換
// this.autoTimer = setInterval(function(){
// _this.autoMove();
// },this.autoInterval);
// 或者這樣寫
// this.autoTimer = setInterval(this.autoMove.bind(this),this.autoInterval);
if (this.needAutoChange) {
this.autoTimer = setInterval(this.autoMove.bind(this), this.autoInterval);
}
//=>13、其它方式切換
this.mouseEvent();
// this.arrowEvent();
// this.eventFocus();
this.delegateEvent();
}
};
// 14、深度擴充套件(類似jq一樣,支援extend自己擴充套件方法,別人可以自己擴充套件方法,)
BannerPlugin.extend = function (obj, deep) {
typeof deep === 'undefined' ? deep = false : null;
for (var key in obj) {
//迴圈obj,替換外掛原有方法,如果傳遞的obj中的方法在原外掛中有,就continue不執行BannerPlugin.prototype[key] = obj[key];
// 如果傳遞的obj中的方法在原外掛中有,並且deep是true的時候,替換到原型上方法執行BannerPlugin.prototype[key] = obj[key];
if (obj.hasOwnProperty(key)) {
if (BannerPlugin.prototype.hasOwnProperty(key)) {
if (deep) {
BannerPlugin.prototype[key] = obj[key];
}
continue;
}
BannerPlugin.prototype[key] = obj[key];
}
}
};
//=>讓INIT的原型指向BANNER-PLUGIN的原型,目的:當執行BANNER-PLUGIN方法的時候建立出來的依然是BANNER-PLUGIN類的例項
BannerPlugin.prototype.init.prototype = BannerPlugin.prototype;
window.$banner = window.BannerPlugin = BannerPlugin;
}();
$banner({
container: document.getElementById('container'),
url: 'json/banner.json',
autoInterval: 3000,
initIndex: 2
});
var bannerExample = $banner({
container: document.getElementById('container2'),
url: 'json/banner2.json',
needFocusChange: false,
isArrowShow: false,
speed: 100,
lazyImgTime: 2000
});
// true深度擴充套件,把外掛原有方法替換掉
// $banner.extend({
// aa: function () {
// }
// }, true);
// bannerExample.aa();//別人可以通過自己擴充套件aa()這個方法做一些其他的功能
//替換原型上的change方法
$banner.extend({
change: function () {
animate({
curEle: this.wrapper,
target: {left: -this.initIndex * this.containerWidth},
duration: this.speed,
effect: animateEffect.Bounce.easeOut
});
//->CHANGE FOCUS
if (this.isFocusShow) {
var tempIndex = this.initIndex;
tempIndex === this.bannerData.length ? tempIndex = 0 : null;
[].forEach.call(this.focusList, function (item, index) {
item.className = index === tempIndex ? 'select' : null;
});
}
}
}, true);
bannerExample.speed = 500;
複製程式碼
banner.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<!--<link rel="stylesheet/less" href="css/banner.less">
<script src="js/less-2.5.3.min.js"></script>-->
<link rel="stylesheet" href="css/banner.min.css">
</head>
<body>
<!--BANNER-->
<div class="container" id="container">
<!--WRAPPER-->
<ul class="wrapper clearfix">
<!--<li class="slide">
<a href="#">
<img src="img/banner1.jpg" alt="">
</a>
</li>-->
</ul>
<!--FOCUS-BOX-->
<ul class="focusBox clearfix">
<!--<li class="select"></li>
<li></li>-->
</ul>
<!--ARROW-->
<a href="javascript:;" class="arrow arrowLeft"></a>
<a href="javascript:;" class="arrow arrowRight"></a>
</div>
<div class="container" id="container2">
<!--WRAPPER-->
<ul class="wrapper clearfix">
</ul>
<!--FOCUS-BOX-->
<ul class="focusBox clearfix">
<!--<li class="select"></li>
<li></li>-->
</ul>
</div>
<!--IMPORT JS-->
<script src="js/utils.min.js"></script>
<script src="js/animate.min.js"></script>
<script src="js/plugin-banner.js"></script>
</body>
</html>
複製程式碼
banner2.json
[
{
"id": 1,
"img": "img/banner1.jpg",
"desc": "推薦機會",
"link": "http://www.baidu.com/"
},
{
"id": 2,
"img": "img/banner2.jpg",
"desc": "夢想起飛",
"link": "http://www.baidu.com/"
},
{
"id": 3,
"img": "img/banner3.jpg",
"desc": "把握未來",
"link": "http://www.baidu.com/"
}
]
複製程式碼