什么是組件?---組件就是對象-
寫組件的目的:減少開發(fā)成本,提供開發(fā)效率
組件是對數(shù)據(jù)和方法的簡單封裝!
特點:可以有自己屬性和方法,屬性是組件數(shù)據(jù)的簡單訪問者。方法是組件的一個簡單而可見的功能!
組件的分類:
復合組件:將現(xiàn)有的各種組件組合起來,形成一個新的組件,將集中組件的性能集中起來
擴展組件:現(xiàn)有的組件派生出的新的組件
自定義組件
組件的三要素:屬性,事件,方法
寫組件的基礎:具備js的面向對象,很精通,css,html,jquery源碼深入學習,對設計模式有很好掌握
設計模式:可以以mvc的模式方式:視圖,數(shù)據(jù)交互,控制層!
?小知識積累:com--表示商業(yè)性質!
前端如何實現(xiàn)封裝性? 根據(jù)解釋了解本質,從而實現(xiàn)關鍵。
需求:
封裝性
獨立性
組件化
可拓展性
可重用性
簡單化
模塊化
什么是封裝性?
封裝性:指一個對象包含了它可接受的信息、行為及內部的屬性和狀態(tài),
其它對象只能通過一定的方法訪問它
而不能訪問其內部的私有數(shù)據(jù)和操作。
解析:包含,可接受的信息(初始化信息和本身信息),行為(內部行為和對
外行為)
Js的封裝性:采用事件驅動模型(利用js的call和apply方法),只負責拋出事件和相應參數(shù),不管相應的處理。所有受影響的標簽由外部傳入,同時對傳入的數(shù)據(jù)最好采用對象屬性模擬,可實現(xiàn)單例模式
今日所收:
簡單的組件寫法:
1寫一個類--構造函數(shù)-- 【構造函數(shù)需要的參數(shù)--屬性,方法調用--this.init(),this.readerDOM,this.bindDom();】;
2.在類的原型上添加方法---
?? 初始化設置--數(shù)據(jù)的初始化
根據(jù)數(shù)據(jù)渲染DOM---寫在類的原型上的功能和方法
綁定DOM事件-構造函數(shù).prototype.bindDOM=function(){
? //手指按下的處理事件
???? var startHandler=function(event){
? };
//手指移動的處理事件
var moveHandler=function(event){
};
//手指抬起的處理事件
var endHandler = function(evt){};
outer.addEventListenter('touchstart',startHandler);
}
//初始化實例
new 構造函數(shù)({
?dom:document.getElmentbyiD(');
lsit:list})
body{
margin: 0;
padding: 0;
background: #333;
overflow: hidden;
}
li,ul{
list-style: none;
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
}
/* 使得圖片居中 webkit-box */
li{
position: absolute;
display: -webkit-box;
-webkit-box-pack: center;
-webkit-box-align: center;
}
li img {
max-width: 100%;
max-height: 100%;
}
/* 隱藏畫布外的內容 */
#canvas{
height: 100%;
width: 100%;
overflow: hidden;
}
實例:
var list = [{
height: 950,
width: 800,
img: "imgs/1.jpg"
},
{
height: 1187,
width: 900,
img: "imgs/2.jpg"
},
{
height: 766,
width: 980,
img: "imgs/3.jpg"
},
{
height: 754,
width: 980,
img: "imgs/4.jpg"
},
{
height: 493,
img: "imgs/5.jpg",
width: 750
},
{
height: 500,
img: "imgs/6.jpg",
width: 750
},
{
height: 600,
img: "imgs/7.jpg",
width: 400
}];
//構造函數(shù)
function Slider(opts){
//構造函數(shù)需要的參數(shù)
this.wrap = opts.dom;
this.list = opts.list;
//構造三步奏
this.init();
this.renderDOM();
this.bindDOM();
}
//第一步 -- 初始化
Slider.prototype.init = function() {
//設定窗口比率
this.radio = window.innerHeight/window.innerWidth;
//設定一頁的寬度
this.scaleW = window.innerWidth;
//設定初始的索引值
this.idx = 0;
};
//第二步 -- 根據(jù)數(shù)據(jù)渲染DOM
Slider.prototype.renderDOM = function(){
var wrap = this.wrap;
var data = this.list;
var len = data.length;
this.outer = document.createElement('ul');
//根據(jù)元素的
for(var i = 0; i < len; i++){
var li = document.createElement('li');
var item = data[i];
li.style.width = window.innerWidth +'px';
li.style.webkitTransform = 'translate3d('+ i*this.scaleW +'px, 0, 0)';
if(item){
//根據(jù)窗口的比例與圖片的比例來確定//圖片是根據(jù)寬度來等比縮放還是根據(jù)高度來等比縮放if(item['height']/item['width'] > this.radio){
li.innerHTML = '<img height="'+window.innerHeight+'" src="'+item['img']+'"/>
}else {
li.innerHMTL='<img width="'+window.innerWidht+'' src='"+'item['img']'+"/>;'
}
}
this.outer.appendChild(li);
}
//UL的寬度和畫布寬度一致
this.outer.style.cssText = 'width:' + this.scaleW +'px';
wrap.style.height = window.innerHeight + 'px';
wrap.appendChild(this.outer);
};
Slider.prototype.goIndex = function(n){
var idx = this.idx;
var lis = this.outer.getElementsByTagName('li');
var len = lis.length;
var cidx;
//如果傳數(shù)字 2,3 之類可以使得直接滑動到該索引
if(typeof n == 'number'){
cidx = idx;
//如果是傳字符則為索引的變化
}else if(typeof n == 'string'){
cidx = idx + n*1;
}
//當索引右超出
if(cidx > len-1){
cidx = len - 1;
//當索引左超出
}else if(cidx < 0){
cidx = 0;
}
//保留當前索引值
this.idx = cidx;
//改變過渡的方式,從無動畫變?yōu)橛袆赢?br>
lis[cidx].style.webkitTransition = '-webkit-transform 0.2s ease-out';
lis[cidx-1] && (lis[cidx-1].style.webkitTransition = '-webkit-transform 0.2s ease-out');
lis[cidx+1] && (lis[cidx+1].style.webkitTransition = '-webkit-transform 0.2s ease-out');
//改變動畫后所應該的位移值
lis[cidx].style.webkitTransform = 'translate3d(0, 0, 0)';
lis[cidx-1] && (lis[cidx-1].style.webkitTransform = 'translate3d(-'+ this.scaleW +'px, 0, 0)');
lis[cidx+1] && (lis[cidx+1].style.webkitTransform = 'translate3d('+ this.scaleW +'px, 0, 0)');
};
//第三步 -- 綁定 DOM 事件
Slider.prototype.bindDOM = function(){
var self = this;
var scaleW = self.scaleW;
var outer = self.outer;
var len = self.list.length;
//手指按下的處理事件
var startHandler = function(evt){
//記錄剛剛開始按下的時間
self.startTime = new Date() * 1;
//記錄手指按下的坐標
self.startX = evt.touches[0].pageX;
//清除偏移量
self.offsetX = 0;
//事件對象
var target = evt.target;
while(target.nodeName != 'LI' && target.nodeName != 'BODY'){
target = target.parentNode;
}
self.target = target;
};
//手指移動的處理事件
var moveHandler = function(evt){
//兼容chrome android,阻止瀏覽器默認行為
evt.preventDefault();
//計算手指的偏移量
self.offsetX = evt.targetTouches[0].pageX - self.startX;
var lis = outer.getElementsByTagName('li');
//起始索引
var i = self.idx - 1;
//結束索引
var m = i + 3;
//最小化改變DOM屬性
for(i; i < m; i++){
lis[i] && (lis[i].style.webkitTransition = '-webkit-transform 0s ease-out');
lis[i] && (lis[i].style.webkitTransform = 'translate3d('+ ((i-self.idx)*self.scaleW + self.offsetX) +'px, 0, 0)');
}
};
//手指抬起的處理事件
var endHandler = function(evt){
evt.preventDefault();
//邊界就翻頁值
var boundary = scaleW/6;
//手指抬起的時間值
var endTime = new Date() * 1;
//所有列表項
var lis = outer.getElementsByTagName('li');
//當手指移動時間超過300ms 的時候,按位移算
if(endTime - self.startTime > 300){
if(self.offsetX >= boundary){
self.goIndex('-1');
}else if(self.offsetX < 0 && self.offsetX < -boundary){
self.goIndex('+1');
}else{
self.goIndex('0');
}
}else{
//優(yōu)化
//快速移動也能使得翻頁
if(self.offsetX > 50){
self.goIndex('-1');
}else if(self.offsetX < -50){
self.goIndex('+1');
}else{
self.goIndex('0');
}
}
};
//綁定事件
outer.addEventListener('touchstart', startHandler);
outer.addEventListener('touchmove', moveHandler);
outer.addEventListener('touchend', endHandler);
};
//初始化Slider 實例
new Slider({
dom : document.getElementById('canvas'),
list : list
});
?