tab.js 1.87 KB
/**
 *  Module: tab.js
 *
 *  markup:
 *  <div class="tab">
 *      <ul class="tab-navs">
 *          <li class="tab-nav active">
 *              <a href="javascript:;" data-trigger="tab" data-target="#a"></a>
 *          </li>
 *          <li class="tab-nav">
 *              <a href="javascript:;" data-trigger="tab" data-target="#b"></a>
 *          </li>
 *      </ul>
 *      <div class="tab-panels">
 *          <div id="a" class="tab-panel">
 *          </div id="b" class="tab-panel">
 *      </div>
 *  </div>
 */


let Tab = function(elem) {
    this.$elem = $(elem);
};

Tab.prototype.show = function() {
    let $nav = this.$elem;
    let targetSelector = (function(elem) {
        let selector = elem.dataset.target;

        if (!selector) {
            selector = elem.getAttribute('href') || '';
            selector = /^#[a-z]/i.test(selector) ? selector : null;
        }

        return selector;
    }($nav[0]));

    let $target = $(targetSelector);

    if ($nav.hasClass('active')) {
        return;
    }

    function active($elem, $parent) {
        $parent.children('.active').removeClass('active');

        $elem.addClass('active');
    }

    active($nav.parent('.tab-nav'), $nav.closest('.tab-navs'));
    active($target, $target.closest('.tab-panels'));
};



function Plugin(option) {
    this.each(function() {
        let $this = $(this);
        let data = $this.data('yoho.tab');
        let options = typeof option === 'object' && option;

        if (!data) {
            $this.data('yoho.tab', (data = new Tab(this, options)));
        }

        if (typeof option === 'string') {
            data[option]();
        }
    });
}

$.fn.yoTab = Plugin;
$.fn.yoTab.constructor = Tab;


$(document).on('click', '[data-trigger=tab]', function(event) {
    event.preventDefault();
    event.stopPropagation();

    let $nav = $(event.target);

    Plugin.call($nav, 'show');
});