零JQ筆記 | 組件小例

架子:

$(function () {
        var t1 = new Tab();
        ti.init('div1', {})
    })

    function Tab() {
        this.settings = { //默認參數
            event: 'click'
        }
    }
    Tab.prototype.init = function (_parent, opt) {
        $.extend(this.settings, opt);


    }

主要分離3方面:


配置參數:opt:events , delay


方法:methos:nowSel(),getContent


事件:beforeClick,afterClick


注意的點:

1、jq中主動解發 $(_this).trigger('afterClick'),相當於 autoEvent(_this, 'afterClick') ;


2、特別留意this指向問題;


3、jq中$.extend(this.settings, opt),相當於 extend(this.settings, opt)


    $(function () {
        var t1 = new Tab();
        t1.init('div1', {})
        var t2 = new Tab();
        t2.init('div2', {
            event:'mouseover'
        })

        var t3 = new Tab();
        t3.init('div3', {
            event:'mouseover',
            delay:200
        })
        var t4 = new Tab();
        t4.init('div4', {})
        t4.nowSel(2)
        $('#inp1').click(function(){
            console.log(t4.getContent());
        })

        $(t4).on('beforeClick', function () {
            console.log(t4.getContent() + ' before');
        })
        $(t4).on('afterClick', function () {
            console.log(t4.getContent() + ' after');
        })

    })

    function Tab() {
        this._parent = null;
        this._inp = null;
        this._div = null;
        this.cur = 0;
        this.settings = { //默認參數
            event: 'click',
            delay:0
        }
    }
    Tab.prototype.init = function (_parent, opt) {
        $.extend(this.settings, opt);
        this._parent = $('#'+_parent);
        this._inp = this._parent.find('input');
        this._div = this._parent.find('div');
        this.change();
    }
    Tab.prototype.change = function () {
        var _this = this;
        var _t = null;
        this._inp.on(this.settings.event,function(){

            var This = this;
            if(_this.settings.event == 'mouseover' && _this.settings.delay){
                _t = setTimeout(function(){
                    show(This)
                },_this.settings.delay);
            }
            else{
                show(this)
            }
        }).mouseout(function () {
            clearTimeout(_t);
        })
        function show(obj){ //obj指按鈕;

            $(_this).trigger('beforeClick') ; //點擊前

            $(obj).attr('class','active').siblings().removeClass('active');
            _this._div.eq($(obj).index()).css('display','block').siblings('div').css('display','none')
            _this.cur = $(obj).index()  //千萬注意this指向,坑

            $(_this).trigger('afterClick') ; //點擊前
        }
    }
    Tab.prototype.nowSel = function(index){
        this._inp.eq(index).attr('class','active').siblings().removeClass('active');
        this._div.eq(index).css('display','block').siblings('div').css('display','none')
        this.cur = index;
    }
    Tab.prototype.getContent = function () {
        return this._div.eq(this.cur).html()
    }

http://tangram.baidu.com/magic/

零JS筆記 | 面向對象 | 自定義事件

什麼是組件?

對面向對象的深入應用(UI組件、功能組件)
將配置參數、方法、事件,三者分離
創建自定義事件:
有利於多人協作開發;
如何去掛載自定義事件與事件函數

自定義事件:主要與函數有關,讓函數具備事件某些特性
(比如,多个函数也可如事件都执行,而不是像同名函数后覆盖前)

原理:

window.onload = function () {
    var _div = document.getElementById('div1')
    var _span = document.getElementById('span1')

    bind(_div, 'click', function () {
        console.log(1);
    })
    bind(_div, 'click', function () {
        console.log(2);
    })

    bind(_span, 'show', function () {
        console.log(3);
    })
    bind(_span, 'show', function () {
        console.log(4);
    })
    bind(_span, 'hide', function () {
        console.log(5);
    })

//觸發自定義事件: 

    autoEvent(_span, 'show') // 3,4
    autoEvent(_span, 'hide') // 3,4


    function bind(obj, events, fn) {   //建立关系 ;
        //obj:楼层;
        //events:书架
        //fn:一本书

        obj.listeners = obj.listeners || {} //樓層
        obj.listeners[events] = obj.listeners[events] || []; //樓層下創建書架
        obj.listeners[events].push(fn); //push方法把對應的書存到書架下


        if (obj.addEventListener) {
            obj.addEventListener(events, fn, false)
        }
        else {
            obj.attachEvent('on' + events, fn)
        }
    }

    function autoEvent(obj, events) {   //主动触发自定义事件;
        for (var i = 0; i < obj.listeners[events].length; i++) {
            obj.listeners[events][i]();   //循環數組執行即可
        }

    }

}

改寫實例:

window.onload = function () {
    var d1 = new Drag()
    var d2 = new Drag()
    var d3 = new Drag()
    var d4 = new Drag()
    d1.init({
        id: 'div1'
    })
    d2.init({
        id: 'div2'
    })
    bind(d2, '_down', function () {
        document.title = 'down'
    })
    d3.init({
        id: 'div3'
    })
    bind(d3, '_up', function () {
        document.title = 'up'
    })
    d4.init({
        id: 'div4'
    })
    bind(d4, '_up', function () {
        document.title = 'bybybybyb'
    })

//所以,最大的好處:如果想讓最後一個變大,只需要再綁定一次即可;而不是寫在原有代碼裏;

    bind(d4, '_up', function () {
        document.getElementById('div4').style.width = '200px'
    })
}
function Drag() {
    this.obj = null;
    this.disX = 0;
    this.dixY = 0;
    this.settings = {}
}
Drag.prototype.init = function (opt) {
    this.obj = document.getElementById(opt.id)
    var _this = this;
    extend(this.settings, opt)
    this.obj.onmousedown = function (ev) {
        var ev = ev || event;
        _this.fnDown(ev)
//執行
        autoEvent(_this, '_down')

        document.onmousemove = function (ev) {
            var ev = ev || event;
            _this.fnMove(ev)
        }
        document.onmouseup = function () {
            _this.fnUp();
//執行
            autoEvent(_this, '_up')

        }
        return false //最後加阻止默認事件;
    }
}
Drag.prototype.fnDown = function (ev) {
    this.disX = ev.clientX - this.obj.offsetLeft;
    this.disY = ev.clientY - this.obj.offsetTop;
}
Drag.prototype.fnMove = function (ev) {
    this.obj.style.left = ev.clientX - this.disX + 'px'
    this.obj.style.top = ev.clientY - this.disY + 'px'
}
Drag.prototype.fnUp = function () {
    document.onmousemove = document.onmouseup = null;
}
function extend(o1, o2) {
    for (var attr in o2) {
        o1[attr] = o2[attr]
    }
}
function bind(obj, events, fn) {
    obj.listeners = obj.listeners || {};
    obj.listeners[events] = obj.listeners[events] || [];
    obj.listeners[events].push(fn);

    if (obj.nodeType) { //判斷是否為dom元素
        if (obj.addEventListener) {
            obj.addEventListener(events, fn, false)
        }
        else {
            obj.attachEvent('on' + events, fn)
        }
    }
}

function autoEvent(obj, events) {
    if (obj.listeners && obj.listeners[events]) { //判斷是否存在
        for (var i = 0; i < obj.listeners[events].length; i++) {
            obj.listeners[events][i]()
        }
    }

}