• javascript继承(七)—用继承的方式实现照片墙功能


    照片墙DEMO下载 注意:图片有四种类型:1可放大;2可拖动;3既可放大也可拖动;4都不行。由于每个图片的构造函数不同而不同(目前在火狐上调试的,其它的浏览器可能不行,请见谅,主要讲继承的思想。以后会考虑兼容性的)

    照片墙的实现是比较容易的,网上也有许许多多的事例。本篇文章将着重介绍一下用继承的方式怎么样去实现。使用继承又能带来怎样的好处。我们知道面向对象的优势在于可扩展性,这篇文章主要就是用面向对象的思想

    下面将具体的介绍如何实现照片墙:

    首先是布局,将所有照片按顺序排列并不难,因为图片的宽高是不固定的,所以这儿只需要定义图片的高就行了,宽度会根据高度来缩放。又因为要实现拖动的效果,所以在这里必须给每张图片加了个属性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; 200px; font-size: 60px;}
    #photo_wall{margin:0 auto;position:relative;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。为了使照片墙更有层次感一点,在代码中添加了一个旋转角度。下面介绍这几个类的作用,首先是父类代码如下:

    /*相片父类,拥有三个方法:
    1、初始化方法旋转一定角度10-50度
    2、鼠标移入恢复正常
    3、移入又偏移相同角度*/
    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,{_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,{_this.sOldWidth,height:_this.sOldHeight});
        }
    }

    可以看到子类1继承了父类的属性和方法,并且对移入和移出的方法进行重写。实现了移入不仅仅恢复偏移角度,还放大3倍的功能,移出则恢复初始状态,这里用到已经封装好的工具函数,引用的utilJs代码。

    下面看看子类2的代码:

    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里。

    而子类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里同样很强大。这儿把每一个图片看作一个对象,分别对每一个对象进行操作,添加功能就是十分方便,当然以后扩展起来也十分容易,只需要去继承父类,实现你想要的效果就行了。

  • 相关阅读:
    SP3267 DQUERY
    P3808 【模板】AC自动机(简单版)
    What Are You Talking About HDU
    【博客同步】【微信首发】GC-server的安装与使用
    博客园界面背景及一些特效设置
    C# 常用特性(Attribute)
    CRC常用参数模型及C#代码实现
    简单实用算法——字节位序反转
    C#串口开发之SerialPort类封装
    C#泛型的类型参数约束
  • 原文地址:https://www.cnblogs.com/lj915/p/3787581.html
Copyright © 2020-2023  润新知