常見設計模式基礎知識問答

一、問答

(一)、寫出 構造函數模式、混合模式、模塊模式、工廠模式、單例模式、發布訂閱模式的范例。
//單例模式范例
var  Car = (function(){
    var instance;
    function init() {
        //私有的變量和函數
        var speed = 0;
        return {
            //定義公共的屬性和方法
            getSpeed: function(){
                return speed;
            },
            setSpeed: function( s ){
               speed = s;
            }
        };
    }
    return {
        getInstance: function() {
            if (!instance) {
                instance = init();
            }
            return instance;
        }
    };
}());
var car = Car.getInstance();
var car2 = Car.getInstance();
car === car2;

1、工廠模式:

    //工廠模式 ---通過函數創造一個對象 將其return出來
    function createPeople(age,name,sex) {
        var o= new Object();
        o.age=age;
        o.name=name;
        o.sex=sex;
        return o;
    }
    var p1=createPeople(18,"zhangsan","M"),
            p2=createPeople(20,"lisi","F");
    console.log(p1,p2)

2、構造函數模式:

    function People(age,name) {
        this.age=age;
        this.name=name;
        this.sayName=function () {
            console.log("I am",this.name)
        }
    }

    var p1=new People("1","gouzao");

3、混合模式

    function People(name,age) {
        this.name=name;
        this.age=age;
    }
    People.prototype.sayAge=function () {
        console.log("my age is",this.age)

    };

    function Students(name,age,teacherName) {
        this.teacherName=teacherName;
        People.call(this,name,age);
    }

    Students.prototype=Object.create(People.prototype);
    Students.prototype.constructor=Students;
    Students.prototype.sayHi=function () {
        console.log("Hi! I am student and my name is"+this.name)
    };

    var student1= new Students("混合",11,"teache11"),
    student2= new Students("混合2",22,"teache22");

4、模塊模式:

    var People=(function () {
        var name="laomingzi";
        return{
            changeName: function (newName) {
                name=newName;
            },
            sayName:function () {
                console.log(name)

            }
        }
    }());
    People.sayName();
    People.changeName("xinmingzi");
    People.sayName();
    
    // 常見形式

   var Car=(function () {
       var carName="奔馳";
       function sayCarName() {
           console.log(carName)
       }
       return{
          sayNameFunc:sayCarName
       }

   }());
    Car.sayNameFunc()

模塊模式相對其他模式來說,安全性會有所提升,例如上面的例子,我們不能夠在外面直接訪問carName這個變量;
模塊模式其實使得js具有一定的封裝功能;

5、單例模式:

    var Singleton = (function () {
        var instantiated;
        function init() {
            /*這里定義單例代碼*/
            return {
                publicMethod: function () {
                    console.log('hello world');
                },
                publicProperty: 'test'
            };
        }

        return {
            getInstance: function () {
                if (!instantiated) {
                    instantiated = init();
                }
                return instantiated;
            }
        };
    })();

    /*調用公有的方法來獲取實例:*/
    Singleton.getInstance().publicMethod();

 // var danli=(function() {
//      var instant;
//      function init() {
//          return {
//              publicMethod: function(){
//                  console.log("我是單例模式")
//              },
//              publicOtherProto:"我是單例模式的OtherProto"
//          }
//      }
//      return{
//          getInstance:function () {
//              if (!instant){
//                  instant=init();
//              }
//              return instant;
//          }
//      }
//
//  }());
//  danli.getInstance().publicMethod();

再舉個單例模式例子:

var SingletonTester = (function () {

    //參數:傳遞給單例的一個參數集合
    function Singleton(args) {

        //設置args變量為接收的參數或者為空(如果沒有提供的話)
        var args = args || {};
        //設置name參數
        this.name = 'SingletonTester';
        //設置pointX的值
        this.pointX = args.pointX || 6; //從接收的參數里獲取,或者設置為默認值
        //設置pointY的值
        this.pointY = args.pointY || 10;

    }

    //實例容器
    var instance;

    var _static = {
        name: 'SingletonTester',

        //獲取實例的方法
        //返回Singleton的實例
        getInstance: function (args) {
            if (instance === undefined) {
                instance = new Singleton(args);
            }
            return instance;
        }
    };
    return _static;
})();

var singletonTest = SingletonTester.getInstance({ pointX: 5 });
console.log(singletonTest.pointX); // 輸出 5

其實單例一般是用在系統間各種模式的通信協調上。

6、發布訂閱模式

//無傳參模式
  EventCenter=(function () {
      var events={};
      return{
          on:function (evt,handle) {
              events[evt]=events[evt]||[];
              events[evt].push(handle);
          },
          fire:function (evt) {
              if (!events[evt]){ console.log("未綁定此事件"); return}
              for(var i=0;i<events[evt].length;i++){
                  events[evt][i]()
              }
          },
          unbind:function (evt) {
              delete events[evt];
          }
      }

  }())

//有參數模式

  EventCenter=(function () {
      var events={};
      return{
          on:function (evt,handle) {
              events[evt]=events[evt]||[];
              events[evt].push({handle:handle});
          },
          fire:function (evt,arg) {
              if (!events[evt]){ console.log("未綁定此事件"); return}
              for(var i=0;i<events[evt].length;i++){
                  events[evt][i].handle(arg)
              }
          },
          unbind:function (evt) {
              delete events[evt];
          }
      }
  }());

(二)、使用發布訂閱模式寫一個事件管理器,可以實現如下方式調用
EventManager.on('text:change', function(val){
    console.log('text:change...  now val is ' + val);  
});
EventManager.fire('text:change', '饑人谷');
EventManager.off('text:change');
    EventManager=(function () {
      var events={};
      return{
          on:function (evt,handle) {
              events[evt]=events[evt]||[];
              events[evt].push(handle);  //{事件1:[函數1,函數2]}
          },
          fire:function (evt) {
              if (!events[evt]){ console.log("未綁定此事件"); return}
              for(var i=0;i<events[evt].length;i++){
                  events[evt][i]([].slice.call(arguments,1))
              }
          },
          off:function (evt) {
              delete events[evt];
          }
      }
  }());

運行結果:

Paste_Image.png

二、代碼

(一)、寫一個函數createTimer,用于創建計時器,創建的計時器可分別進行計時「新增」。

ps: 1. 計時器內部寫法參考前面的任務中Runtime的寫法; 2. 體會工廠模式的用法

function createTimer(){
    //todo..    
}

var timer1 = createTimer();
var timer2 = createTimer();
timer1.start();
for(var i=0;i<100;i++){
    console.log(i);
}
timer2.start();
for(var i=0;i<100;i++){
    console.log(i);
}
timer1.end();
timer2.end();
console.log(timer1.get());
console.log(timer2.get());

代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    function createTimer(){
        var startTime,
            endTime,
            difference;

        var timer={
            start: function () {
                startTime=Date.now();
                return  startTime
            },
            end: function () {
                endTime=Date.now();
                return endTime
            },
            get:function () {
                difference=endTime-startTime;
                return difference
            }
        };

        return timer
    }

    var timer1 = createTimer();
    var timer2 = createTimer();

    timer1.start();
    for(var i=0;i<100;i++){
        console.log(i);
    }

    timer1.end();

    alert("timer1的執行時間是"+timer1.get());

    timer2.start();
    for(var i=0;i<1000;i++){
        console.log(i);
    }
    timer2.end();
    alert("timer2的執行時間是"+timer2.get());

</script>

</body>
</html>
(二)、封裝一個曝光加載組件,能實現如下方式調用
//$target 是 jquery 對象
// 當窗口滾動時,如果$target 出現在可見區域,執行回調函數里面的代碼,且在回調函數內,$(this)代表$target
Expouse.bind($target, function(){
    console.log($(this));    // $target
});
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
    <style>
        li{
            height: 30px;
            background-color: aqua;
        }
    </style>
</head>
<body>
<ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li class="target"> i am target</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>
<script>    
    $(window).on("scroll",function () {
        var $target=$(".target");

        function isVisible($node) {
            var scrollH=$(window).scrollTop(),
                    $nodeOffsetH=$node.offset().top,
                    $nodeHeight=$node.outerHeight(true),
                    windowH=$(window).height();

            if ((scrollH+windowH)>$nodeOffsetH &&(scrollH+windowH)<($nodeHeight+$nodeOffsetH) ){
                return true
            }else {return false}
            
        }
        Expouse=(function(){
            function bind(evt,callback) {
                callback.call(evt)
            }
            return {
                bind:bind
            }

        }());
        if (isVisible($target)){
            Expouse.bind($target, function(){
                console.log($(this));    // $target
            });
        }        
    });

</script>

</body>
</html>

// 當窗口滾動時,如果$target 出現在可見區域,執行回調函數里面的代碼,且在回調函數內,$(this)代表$target。 僅執行一次回調函數,下次$target 曝光不再執行
Expourse.one($target, function(){
    console.log($(this));    // $target
})
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
    <style>
        li{
            height: 30px;
            background-color: aqua;
        }
    </style>
</head>
<body>
<ul>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li class="target"> i am target</li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>

<script>
//    //$target 是 jquery 對象
//    // 當窗口滾動時,如果$target 出現在可見區域,執行回調函數里面的代碼,且在回調函數內,$(this)代表$target
//    Expouse.bind($target, function(){
//        console.log($(this));    // $target
//    });
    
    $(window).on("scroll",function () {
        var $target=$(".target");

        if ($target.data("isrun")){
            return
        }

        function isVisible($node) {
            var scrollH=$(window).scrollTop(),
                    $nodeOffsetH=$node.offset().top,
                    $nodeHeight=$node.outerHeight(true),
                    windowH=$(window).height();

            if ((scrollH+windowH)>$nodeOffsetH &&(scrollH+windowH)<($nodeHeight+$nodeOffsetH) ){
                return true
            }else {return false}
            
        }
        Expouse=(function(){
            function bind(evt,callback) {
                callback.call(evt)
            }
            return {
                bind:bind
            }

        }());
        if (isVisible($target)){
            Expouse.bind($target, function(){
                console.log($(this));    // $target
            });
            $target.data("isrun",true)

        }
        
    });


</script>

</body>
</html>
(三)、封裝一個 輪播插件,分別使用對象方式和 jquery插件方式來調用
// 要求:html 里有多個carousel,當調用時啟動全部的 carousel

//方式1
//通過插件的方式啟動所有輪播
$('.carousel').carousel();

//方式2
//通過創建對象的方式啟動所有輪播
$('.carousel').each(function(){
    new Carousel($(this));
});

a、 插件方法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>27-1無限輪播</title>
    <style>
        ul,li{
            list-style: none;
        }
        *{
            margin: 0;
            padding: 0;
        }
        .ct-img>li{
            float: left;
            width: 310px;
            height: 210px;
            display: none;
        }
        li img{
            width: 310px;
            height: 210px;
        }

        .clearfix:after{
            content: "";
            display: block;
            clear: both;
        }
        .ct-bottom>li{
            border-bottom: 5px solid #555;
            float: left;
            cursor: pointer;
            width: 20px;
            margin: 0 5px;
            border-radius: 2px;
        }
        .ct-bottom{
            position: absolute;
            top: 180px;
            left: 95px;
        }
        .ct{
            position: relative;
        }
        a.change{
            text-decoration: none;
            font-size: larger;
            font-weight: 900;
            background-color: #666;
            color: #fff;
            display: inline-block;
            vertical-align: middle;
            padding: 15px;
            width: 10px;
            height: 10px;
            line-height: 10px;
            border-radius: 25px;
            opacity: 0.7;
        }
        a.pre{
            position: absolute;
            left: 10px;
            top: 80px;
        }
        a.next{
            position: absolute;
            left: 250px;
            top: 80px;
        }
        a.change:hover{
            background-color: #444;
        }

    </style>
    <script type="text/javascript" src="http://gc.kis.scr.kaspersky-labs.com/09DC0C47-7E28-5643-A354-E60E2E2E8CBA/main.js" charset="UTF-8"></script></head>
<body>
<div id="wrap">
    <div class="ct">
        <ul class="clearfix ct-img">
            <li data-nub="0"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-9c8f261bdec45ee9.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="1"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-d3fb17e0327a0cc7.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="2"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-e6a8ad9a57c5c17c.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="3"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-b7bdbfa69d0ec3c4.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
        </ul>
        <ul class="ct-bottom clearfix">
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
        <a href="####" class="pre change"> < </a>
        <a href="####" class="next change"> > </a>

    </div>
    <div class="ct">
        <ul class="clearfix ct-img">
            <li data-nub="0"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-e6a8ad9a57c5c17c.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="1"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-d3fb17e0327a0cc7.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="2"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-9c8f261bdec45ee9.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="3"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-b7bdbfa69d0ec3c4.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
        </ul>
        <ul class="ct-bottom clearfix">
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
        <a href="####" class="pre change"> < </a>
        <a href="####" class="next change"> > </a>

    </div>
    <div class="ct">
        <ul class="clearfix ct-img">
            <li data-nub="0"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-9c8f261bdec45ee9.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="1"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-d3fb17e0327a0cc7.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="2"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-e6a8ad9a57c5c17c.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="3"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-b7bdbfa69d0ec3c4.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
        </ul>
        <ul class="ct-bottom clearfix">
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
        <a href="####" class="pre change"> < </a>
        <a href="####" class="next change"> > </a>

    </div>
</div>
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
<script>


    /* 自定義jQuery方法(開發jQuery插件常用此方法) 其實 $.fn === $.prototype */
    $.fn.allGo = function() {
        this.each(function () {
        var $me=$(this),
                $ctImg=$me.find(".ct-img"),
                $ctBottom=$me.find(".ct-bottom"),
                $next=$me.find(".next"),
                $pre=$me.find(".pre"),
                $ctBottomLi=$me.find(".ct-bottom>li"),
                clock=false,
                cur=0;
        show(0);
        setInterval(function () {
            playNext()
        }, 2000);

        function show(num) {
            if (clock) {
                return;
            }
            clock = true;
            $ctBottom.children().eq(num).css("border-bottom-color", "white");
            $ctBottom.children().eq(num).siblings().css("border-bottom-color", "#555");
            $ctImg.children().eq(num).siblings().css("display", "none");
            $ctImg.children().eq(num).fadeOut(500);
            $ctImg.children().eq(num).fadeIn(500, function () {
                clock = false
            });
            cur = num;
            return cur;
        }

        function playNext() {
            var nextNum = cur + 1;
            if (nextNum === 4) {
                show(0)
            }
            else show(nextNum)
        }

        $next.on("click", function () {
            playNext();
        });

        $pre.on("click", function () {
            playPre();
        });

        function playPre() {
            var preNum = cur - 1;
            if (preNum === -1) {
                show(3)
            }
            else show(preNum)
        }

        $ctBottomLi.on("click", function () {
            var $cur = $(this),
                    indexNum = $cur.index();
            show(indexNum);
        });

        });

    };

//    $(".ct").each(function () {
//        $(this).allGo();
//    });

    $('.ct').allGo();
</script>

</body>
</html>

b、創建對象方法:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>27-1無限輪播</title>
    <style>
        ul,li{
            list-style: none;
        }
        *{
            margin: 0;
            padding: 0;
        }
        .ct-img>li{
            float: left;
            width: 310px;
            height: 210px;
            display: none;
        }
        li img{
            width: 310px;
            height: 210px;
        }

        .clearfix:after{
            content: "";
            display: block;
            clear: both;
        }
        .ct-bottom>li{
            border-bottom: 5px solid #555;
            float: left;
            cursor: pointer;
            width: 20px;
            margin: 0 5px;
            border-radius: 2px;
        }
        .ct-bottom{
            position: absolute;
            top: 180px;
            left: 95px;
        }
        .ct{
            position: relative;
        }
        a.change{
            text-decoration: none;
            font-size: larger;
            font-weight: 900;
            background-color: #666;
            color: #fff;
            display: inline-block;
            vertical-align: middle;
            padding: 15px;
            width: 10px;
            height: 10px;
            line-height: 10px;
            border-radius: 25px;
            opacity: 0.7;
        }
        a.pre{
            position: absolute;
            left: 10px;
            top: 80px;
        }
        a.next{
            position: absolute;
            left: 250px;
            top: 80px;
        }
        a.change:hover{
            background-color: #444;
        }

    </style>
    <script type="text/javascript" src="http://gc.kis.scr.kaspersky-labs.com/09DC0C47-7E28-5643-A354-E60E2E2E8CBA/main.js" charset="UTF-8"></script></head>
<body>
<div id="wrap">
    <div class="ct">
        <ul class="clearfix ct-img">
            <li data-nub="0"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-9c8f261bdec45ee9.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="1"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-d3fb17e0327a0cc7.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="2"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-e6a8ad9a57c5c17c.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="3"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-b7bdbfa69d0ec3c4.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
        </ul>
        <ul class="ct-bottom clearfix">
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
        <a href="####" class="pre change"> < </a>
        <a href="####" class="next change"> > </a>

    </div>
    <div class="ct">
        <ul class="clearfix ct-img">
            <li data-nub="0"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-e6a8ad9a57c5c17c.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="1"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-d3fb17e0327a0cc7.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="2"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-9c8f261bdec45ee9.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="3"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-b7bdbfa69d0ec3c4.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
        </ul>
        <ul class="ct-bottom clearfix">
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
        <a href="####" class="pre change"> < </a>
        <a href="####" class="next change"> > </a>

    </div>
    <div class="ct">
        <ul class="clearfix ct-img">
            <li data-nub="0"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-9c8f261bdec45ee9.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="1"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-d3fb17e0327a0cc7.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="2"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-e6a8ad9a57c5c17c.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
            <li data-nub="3"><a href="#">![](http://upload-images.jianshu.io/upload_images/2166980-b7bdbfa69d0ec3c4.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)</a></li>
        </ul>
        <ul class="ct-bottom clearfix">
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
        <a href="####" class="pre change"> < </a>
        <a href="####" class="next change"> > </a>

    </div>
</div>
<script type="text/javascript" src="http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
<script>


    function Carousel($node) {
        this.$node=$node;
        var     $me=this.$node,
                $ctImg=$me.find(".ct-img"),
                $ctBottom=$me.find(".ct-bottom"),
                $next=$me.find(".next"),
                $pre=$me.find(".pre"),
                $ctBottomLi=$me.find(".ct-bottom>li"),
                clock=false,
                cur=0;
        show(0);
        setInterval(function () {
            playNext()
        }, 2000);

        function show(num) {
            if (clock) {
                return;
            }
            clock = true;
            $ctBottom.children().eq(num).css("border-bottom-color", "white");
            $ctBottom.children().eq(num).siblings().css("border-bottom-color", "#555");
            $ctImg.children().eq(num).siblings().css("display", "none");
            $ctImg.children().eq(num).fadeOut(500);
            $ctImg.children().eq(num).fadeIn(500, function () {
                clock = false
            });
            cur = num;
            return cur;
        }

        function playNext() {
            var nextNum = cur + 1;
            if (nextNum === 4) {
                show(0)
            }
            else show(nextNum)
        }

        $next.on("click", function () {
            playNext();
        });

        $pre.on("click", function () {
            playPre();
        });

        function playPre() {
            var preNum = cur - 1;
            if (preNum === -1) {
                show(3)
            }
            else show(preNum)
        }

        $ctBottomLi.on("click", function () {
            var $cur = $(this),
                    indexNum = $cur.index();
            show(indexNum);
        });


    }

    $('.ct').each(function(){
        new Carousel($(this));
    })
</script>

</body>
</html>

另:JavaScript模式相關書籍
1、JavaScript模式 https://book.douban.com/subject/11506062/
2、JavaScript設計模式 https://book.douban.com/subject/3329540/
3、JavaScript設計模式與開發實踐 https://book.douban.com/subject/26382780/

**本文版權歸本人即簡書筆名:該賬戶已被查封 所有,如需轉載請注明出處。謝謝! *

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容