javascript繼承(七)—用繼承的方式實現照片牆功能

照片牆DEMO下載 注意:圖片有四種類型:1可放大;2可拖動;3既可放大也可拖動;4都不行。因爲每一個圖片的構造函數不一樣而不一樣(目前在火狐上調試的,其它的瀏覽器可能不行,請見諒,主要講繼承的思想。之後會考慮兼容性的)html

照片牆的實現是比較容易的,網上也有許許多多的事例。本篇文章將着重介紹一下用繼承的方式怎麼樣去實現。使用繼承又能帶來怎樣的好處。咱們知道面向對象的優點在於可擴展性,這篇文章主要就是用面向對象的思想web

下面將具體的介紹如何實現照片牆:數組

首先是佈局,將全部照片按順序排列並不難,由於圖片的寬高是不固定的,因此這兒只須要定義圖片的高就好了,寬度會根據高度來縮放。又由於要實現拖動的效果,因此在這裏必須給每張圖片加了個屬性positon:absolute。簡單的看下佈局代碼以下:瀏覽器

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>照片牆</title>
<style>
*{margin:0;padding:0}
body{background:#DBDCD6}
.wallTitle{margin:20px auto; width:200px; font-size: 60px;}
#photo_wall{margin:0 auto;position:relative;width:1100px;}
#photo_wall img{
    height:80px;
    border: 7px solid #FFFFFF;
    box-shadow: 1px 1px 1px #AAAAAA;
    margin:20px;
    cursor:pointer;    
    position:absolute;
    z-index:1;    
}

</style>
</head>
<body>
<div class="wallTitle">照片牆</div>   
<div id="photo_wall"></div> 
</body>
<script src="js/utilJs.js"></script>
<script src="js/Photo.js"></script>
<script src="js/PhotoChild1.js"></script>
<script src="js/PhotoChild2.js"></script>
<script src="js/PhotoChild3.js"></script>
<script>
window.onload = function(){
    var oDiv = document.getElementById('photo_wall')
    ,aWallHtmlArray = [] //拼接字符串數組
    ,aPhotoArray = []; //相片路徑地址    
    for(var i =0;i<100;i++){
        aPhotoArray.push('images/'+(1+Math.round(Math.random()*9))+'.jpg');//產生1到10的圖片路徑        
         var sImgLeft = 140*(i%8);
        var sImgTop = 150*(Math.ceil((i+1)/8)-1);
        aWallHtmlArray.push('<img id="photo_'+i+'" src="'+aPhotoArray[i]+'" style="left:'+sImgLeft+'px;top:'+sImgTop+'px"/>');        
    }
    oDiv.innerHTML = aWallHtmlArray.join('');
    
    for(var i =0;i<100;i++){
        var id = 'photo_'+i;        
        var rotateAngle = i%2==0?10+Math.round(Math.random()*40):-10+Math.round(Math.random()*(-40));//旋轉角度                
        switch(i%4){
            case 0:
              new PhotoChild1('photo_'+i,rotateAngle);//放大縮小
              break;
            case 1:
              new PhotoChild2('photo_'+i,rotateAngle);//可拖動
              break;
            case 2:
              new PhotoChild3('photo_'+i,rotateAngle);//即放大又可拖動
              break;
            default:
              new Photo('photo_'+i,rotateAngle);//只能旋轉
        }        
    }
}
</script>
</html>

由於須要添加的圖片比較多,因此直接在js裏進行字符串拼接的的。經過上面的代碼能夠看到,咱們建立了四個類,即父類 Photo,子類1 PhotoChild1,子類2 PhotoChild2,子類3 PhotoChild3。爲了使照片牆更有層次感一點,在代碼中添加了一個旋轉角度。下面介紹這幾個類的做用,首先是父類代碼以下:dom

/*相片父類,擁有三個方法:
一、初始化方法旋轉必定角度10-50度
二、鼠標移入恢復正常
三、移入又偏移相同角度*/
function Photo(sPhotoId,rotateAngle){
    this.oPhoto = document.getElementById(sPhotoId);
    this.rotateAngle = rotateAngle;
    this.rotate();
    this.mouseEnter();
    this.mouseLeave();
}

Photo.prototype = {
    //旋轉必定角度
    rotate:function(){
        var sRotate = 'rotate('+this.rotateAngle+'deg)';
        this.oPhoto.style.transform = sRotate;
        this.oPhoto.style.MozTransform = sRotate;
        this.oPhoto.style.webkitTransform = sRotate;
    },
    
    mouseEnter:function(){
        var _this = this;
        _this.oPhoto.onmouseenter = function(){
            var sRotate = 'rotate(0deg)';
            _this.oPhoto.style.transform = sRotate;
            _this.oPhoto.style.MozTransform = sRotate;
            _this.oPhoto.style.webkitTransform = sRotate;
        }
    },
    
    mouseLeave:function(){
        var _this = this;
        _this.oPhoto.onmouseleave = function(){
            var sRotate = 'rotate('+_this.rotateAngle+'deg)';
            _this.oPhoto.style.transform = sRotate;
            _this.oPhoto.style.MozTransform = sRotate;
            _this.oPhoto.style.webkitTransform = sRotate;
        }
    }
}

做爲父類有三個方法,旋轉角度,在頁面的初始化時調用,鼠標移入移出,在父類中主要實現圖片角度的調整功能。即移入圖片正常顯示,移出偏移必定角度。函數

子類1代碼:工具

//子類1繼承Photo,重寫了父類的mouseEnter和mouseLeave,實現移動放大移出縮小功能
function PhotoChild1(sPhotoId,rotateAngle){
    Photo.call(this,sPhotoId,rotateAngle);    
    this.sOldHeight = getStyle(this.oPhoto,'height').replace('px','');
    this.sOldWidth = getStyle(this.oPhoto,'width').replace('px','');    
}

function Empty(){}
Empty.prototype = Photo.prototype;
PhotoChild1.prototype = new Empty();
PhotoChild1.prototype.constructor = PhotoChild1;

//重寫鼠標移入方法
PhotoChild1.prototype.mouseEnter = function(){
    var _this = this;
    _this.oPhoto.onmouseenter = function(){
        var sRotate = 'rotate(0deg)';
        _this.oPhoto.style.transform = sRotate;
        _this.oPhoto.style.MozTransform = sRotate;
        _this.oPhoto.style.webkitTransform = sRotate;        
        _this.oPhoto.style.zIndex = 2;            
        startMove(_this.oPhoto,{width:_this.sOldWidth*3,height:_this.sOldHeight*3});
    }
}

//重寫鼠標移出方法
PhotoChild1.prototype.mouseLeave = function(){
    var _this = this;
    _this.oPhoto.onmouseleave = function(){
        var sRotate = 'rotate('+_this.rotateAngle+'deg)';
        _this.oPhoto.style.transform = sRotate;
        _this.oPhoto.style.MozTransform = sRotate;
        _this.oPhoto.style.webkitTransform = sRotate;
        _this.oPhoto.style.zIndex = 1;        
        startMove(_this.oPhoto,{width:_this.sOldWidth,height:_this.sOldHeight});
    }
}

能夠看到子類1繼承了父類的屬性和方法,而且對移入和移出的方法進行重寫。實現了移入不單單恢復偏移角度,還放大3倍的功能,移出則恢復初始狀態,這裏用到已經封裝好的工具函數,引用的utilJs代碼。佈局

下面看看子類2的代碼:ui

function PhotoChild2(sPhotoId,rotateAngle){
    Photo.call(this,sPhotoId,rotateAngle);    
    this.sOldHeight = getStyle(this.oPhoto,'height').replace('px','');
    this.sOldWidth = getStyle(this.oPhoto,'width').replace('px','');    
    this.drag();
}

function Empty(){}
Empty.prototype = Photo.prototype;
PhotoChild2.prototype = new Empty();
PhotoChild2.prototype.constructor = PhotoChild2;

PhotoChild2.prototype.drag = function(){
    new Drag(this.oPhoto);
}

也繼承了父類的屬性和方法,而且新加了一個共有方法drag,即實現了可拖動的功能,固然這個類也引用了Drag這個方法,一樣也在utilJs裏。this

而子類3的代碼以下:

//繼承父類,擴展新增了拖動方法
function PhotoChild3(sPhotoId,rotateAngle){    
    PhotoChild2.call(this,sPhotoId,rotateAngle);
    PhotoChild1.call(this,sPhotoId,rotateAngle);
    this.drag();
}

for(var i in PhotoChild2.prototype){PhotoChild3.prototype[i] = PhotoChild2.prototype[i]}
for(var i in PhotoChild1.prototype){PhotoChild3.prototype[i] = PhotoChild1.prototype[i]}

能夠看到子類3繼承了子類1和子類2,實現了一個多繼承,固然對於js裏的多繼承可能存在各類各樣的問題,這裏不一一討論,但咱們這兒利用多繼承讓子類3實現了子類1和子類2的方法。便可以放大、拖動。

總結:經過這個事例,能夠看到面向對象的思想在js裏一樣很強大。這兒把每個圖片看做一個對象,分別對每個對象進行操做,添加功能就是十分方便,固然之後擴展起來也十分容易,只須要去繼承父類,實現你想要的效果就好了。

相關文章
相關標籤/搜索