mackxu
子曰:学而时习之,不亦说乎?

自定义事件是一种处理与DOM产生交互的代码逻辑片段之间耦合的很好的架构方法。

一个简单的jQuery插件——选项卡

让ul列表来响应点击事件。当用户点击一个列表项时,给这个列表项添加一个名为active的类,同时将其他列表项中的active类移除:

<ul id="tabs">
    <li data-tab="users">users</li>
    <li data-tab="groups">groups</li>
</ul>
<div id="tabsContent">
    <div data-tab="users">uuuuuuuuuu</div>
    <div data-tab="groups">ggggggggg</div>
</div>

一般处理方式

jQuery.fn.tabs = function(control) {
    var $tabs = $(this),
        $control = $(control);

    $tabs.find('li').click(function() {
        // 从列表项中删除和添加active类
        $tabs.find('li').removeClass('active');
        this.className = 'active';

        // 对应内容的显示
        var tabName = $(this).attr('data-tab');
        $control.find('[data-tab]').hide();
        $control.find('[data-tab="' + tabName +'"]').show();
    });
    
    // 初始化状态
    $tabs.find('li:first').addClass('active');                // 选中选项卡
    $control.find('>[data-tab]').hide().first().show();        // 只显示第一个div

    return this;
};

现在看上去插件没有什么问题。但可以做下列优化:我们给所有的列表项都添加了click事件回调,可以用事件委托来优化它;点击事件回调的实现很臃肿,很难一眼看出发生了什么;最后,如果另一个开发者想要扩展这个插件,他很可能会将其重写。

优化后的代码

使用自定义事件让代码变得更加整洁。

在点击选项卡时触发一个change.tabs事件,并绑定若干回调方法来适当修改active类。

// 自定义事件tabs.change
// 缓存选项卡元素,减少DOM直接查找
jQuery.fn.tabs2 = function(control) {
    var $tabs = $(this),
        $control = $(control),
        $lis = $tabs.find('li');

    // 利用事件委托,监听单击选项卡事件
    $tabs.on('li', 'click', function() {
        // 单击的选项卡的data-tab属性值
        // var tabName = $(this).attr('data-tab');
        var tabName = this.getAttribute('data-tab');        // 自定义属性需要用getAttribute()获取
        // 在单击时触发自定义事件
        $tabs.trigger('change.tabs', tabName);
    });

    // 绑定自定义事件
    // 解耦回调函数,易扩展
    $tabs.bind('change.tabs', function(e, tabName) {
        $lis.removeClass('active').filter('[data-tab="'+ tabName +'"]').addClass('active');
    });

    $tabs.bind('tabs.change', function(e, tabName) {
        $control.find('>[data-tab]').hide();
        $control.find('>[data-tab="'+ tabName +'"]').show();
    });

    // 初始化状态
    var firstName = $lis.first().attr('data-tab');
    $tabs.trigger('tabs.change', firstName);

    return this;
};

 

posted on 2013-06-28 09:16  mackxu  阅读(823)  评论(0编辑  收藏  举报