常见设计模式基础知识问答

一、问答

(一)、写出 构造函数模式、混合模式、模块模式、工厂模式、单例模式、发布订阅模式的范例。
//单例模式范例
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/

**本文版权归本人即简书笔名:该账户已被查封 所有,如需转载请注明出处。谢谢! *

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,069评论 4 358
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,212评论 1 287
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 105,912评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,424评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,741评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,194评论 1 206
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,553评论 2 307
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,289评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,923评论 1 237
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,251评论 2 240
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,775评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,144评论 2 249
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,698评论 3 228
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,936评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,658评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,214评论 2 267
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,159评论 2 258

推荐阅读更多精彩内容