API Docs for: 0.1
Show:

File: ../comps/Tab/Tab.js

;(function($){
    !window.UXC && (window.UXC = { log:function(){} });

    window.Tab = UXC.Tab = Tab;
    /**
     * Tab 菜单类
     * <br />DOM 加载完毕后
     * , 只要鼠标移动到具有识别符的Tab上面, Tab就会自动初始化, 目前可识别: <b>.js_autoTab</b>( CSS class )
     * <br />需要手动初始化, 请使用: var ins = new UXC.Tab( _tabSelector );
     * <p>
     *      <b> Tab 容器的HTML属性 </b>
     *      <br /><b>tablabels</b>: 声明 tab 标签的选择器语法
     *      <br /><b>tabcontainers</b>: 声明 tab 容器的选择器语法
     *      <br /><b>tabactiveclass</b>: 声明 tab当前标签的显示样式名, 默认为 cur
     *      <br /><b>tablabelparent</b>: 声明 tab的当前显示样式是在父节点, 默认为 tab label 节点
     *      <br /><b>tabactivecallback</b>: 当 tab label 被触发时的回调
     *      <br /><b>tabchangecallback</b>: 当 tab label 变更时的回调
     * </p>
     * <p>
     *      <b> Label(标签) 容器的HTML属性(AJAX) </b>
     *      <br /><b>tabajaxurl</b>: ajax 请求的 URL 地址
     *      <br /><b>tabajaxmethod</b>: ajax 请求的方法( get|post ), 默认 get
     *      <br /><b>tabajaxdata</b>: ajax 请求的 数据, json
     *      <br /><b>tabajaxcallback</b>: ajax 请求的回调
     * </p>
     * <p><b>require</b>: <a href='window.jQuery.html'>jQuery</a></p>
     * <p><a href='https://github.com/suchesqiu/360UXC.git' target='_blank'>UXC Project Site</a>
     * | <a href='http://uxc.btbtd.org/uxc_docs/classes/UXC.Tab.html' target='_blank'>API docs</a>
     * | <a href='../../comps/Tab/_demo/' target='_blank'>demo link</a></p>
     * @namespace UXC
     * @class Tab
     * @constructor
     * @param   {selector|string}   _selector       要初始化的 Tab 选择器
     * @param   {selector|string}   _triggerTarget  初始完毕后要触发的 label
     * @version dev 0.1
     * @author  qiushaowei   <suches@btbtd.org> | 360 75 Team
     * @date    2013-07-04
     * @example
            <link href='../../../comps/Tab/res/default/style.css' rel='stylesheet' />
            <script src="../../../lib.js"></script>
            <script>
                UXC.debug = 1;
                UXC.use( 'Tab' );

                httpRequire();

                function tabactive( _evt, _container, _tabIns ){
                    var _label = $(this);
                    UXC.log( 'tab ', _evt.type, _label.html(), new Date().getTime() );
                    if( UXC.Tab.isAjax( _label ) && ! UXC.Tab.isAjaxInited( _label ) ){
                        _container.html( '<h2>内容加载中...</h2>' );
                    }
                }

                function tabchange( _container, _tabIns ){
                    var _label = $(this);
                    UXC.log( 'tab change: ', _label.html(), new Date().getTime() );
                }

                $(document).ready( function(){
                    UXC.Tab.ajaxCallback =
                        function( _data, _label, _container ){
                            _data && ( _data = $.parseJSON( _data ) );
                            if( _data && _data.errorno === 0 ){
                                _container.html( printf( '<h2>UXC.Tab.ajaxCallback</h2>{0}', _data.data ) );
                            }else{
                                Tab.isAjaxInited( _label, 0 );
                                _container.html( '<h2>内容加载失败!</h2>' );
                            }
                        };
                });

                function ajaxcallback( _data, _label, _container ){
                    _data && ( _data = $.parseJSON( _data ) );
                    if( _data && _data.errorno === 0 ){
                        _container.html( printf( '<h2>label attr ajaxcallback</h2>{0}', _data.data ) );
                    }else{
                        Tab.isAjaxInited( _label, 0 );
                        _container.html( '<h2>内容加载失败!</h2>' );
                    }
                };
            </script>

            <dl class="def">
                <dt>UXC.Tab 示例 - 静态内容</dt>
                <dd>
                <div class="le-tabview js_autoTab" tablabels="ul.js_tabLabel > li > a" tabcontainers="div.js_tabContent > div" 
                                                    tabactiveclass="active" tablabelparent="li" 
                                                    tabactivecallback="tabactive" tabchangecallback="tabchange"
                                                    >
                        <ul class="le-tabs js_tabLabel">
                            <li class="active"><a href="javascript:">电视剧</a></li>
                            <li><a href="javascript:">电影</a></li>
                            <li><a href="javascript:">综艺</a></li>
                            <li><a href="javascript:">热点</a></li>
                        </ul>
                        <div class="views js_tabContent">
                            <div class="view-item active">1. 集地议送能拿距还杨雷火,永鲜提只风超洋轻绿动视落清各只江执口。</div>
                            <div class="view-item">2. 相送黄血富打万念却烟会华它表本雷烟形烟消卷效难标否标滑固小实。</div>
                            <div class="view-item">3. 理往局背剧养认被站推简沉形括於穿短,精白自没路绿往优八益是入。</div>
                            <div class="view-item">4. 鲁杆格滑那双来班五材实死听顶脱本续克修先课丝另乡型茶父报孔图。</div>
                        </div>
                    </div>
                </dd>
            </dl>

            <dl class="def">
                <dt>UXC.Tab 示例 - 动态内容 - AJAX</dt>
                <dd>
                <div class="le-tabview js_autoTab" tablabels="ul.js_tabLabel2 > li > a" tabcontainers="div.js_tabContent2 > div" 
                                                    tabactiveclass="active" tablabelparent="li" 
                                                    tabactivecallback="tabactive" tabchangecallback="tabchange"
                                                    >
                        <ul class="le-tabs js_tabLabel2">
                            <li class="active"><a href="javascript:">电视剧</a></li>
                            <li><a href="javascript:" tabajaxurl="data/test.php" tabajaxmethod="post" 
                                                      tabajaxdata="{a:1,b:2}" tabajaxcallback="ajaxcallback" >电影</a></li>
                            <li><a href="javascript:" tabajaxurl="data/test.php" tabajaxcallback="ajaxcallback" >综艺</a></li>
                            <li><a href="javascript:" tabajaxurl="data/test.php" >热点</a></li>
                        </ul>
                        <div class="views js_tabContent2">
                            <div class="view-item active">1. 集地议送能拿距还杨雷火,永鲜提只风超洋轻绿动视落清各只江执口。</div>
                            <div class="view-item"></div>
                            <div class="view-item"></div>
                            <div class="view-item"></div>
                        </div>
                    </div>
                </dd>
            </dl>
     */
    function Tab( _selector, _triggerTarget ){
        _selector && ( _selector = $( _selector ) );
        _triggerTarget && ( _triggerTarget = $( _triggerTarget) );
        if( Tab.getInstance( _selector ) ) return Tab.getInstance( _selector );
        /**
         * Tab 模型类的实例
         * @property    _model
         * @type    UXC.Tab.Model
         * @private
         */
        this._model = new Model( _selector, _triggerTarget );
        /**
         * Tab 视图类的实例
         */
        this._view = new View( this._model );

        UXC.log( 'initing tab' );
        this._init();
    }
    /**
     * 页面加载完毕后, 是否要添加自动初始化事件
     * <br /> 自动初始化是 鼠标移动到 Tab 容器时去执行的, 不是页面加载完毕后就开始自动初始化
     * @property    autoInit
     * @type        bool
     * @default     true
     * @static
     */
    Tab.autoInit = true;
    /**
     * label 当前状态的样式
     * @property    activeClass
     * @type        string
     * @default     cur
     * @static      
     */
    Tab.activeClass = 'cur';
    /**
     * label 的触发事件
     * @property    activeEvent
     * @type        string
     * @default     click
     * @static
     */
    Tab.activeEvent = 'click';
    /**
     * 获取或设置 Tab 容器的 Tab 实例属性
     * @method  getInstance
     * @param   {selector}  _selector
     * @param   {UXC.Tab}   _setter     _setter 不为空是设置
     * @static
     */
    Tab.getInstance = 
        function( _selector, _setter ){
            var _r;
            _selector && ( _selector = $(_selector) ).length && (
                typeof _setter != 'undefined' && _selector.data('TabInstance', _setter)
                , _r =  _selector.data('TabInstance')
            );
            return _r;
        };
    /**
     * 全局的 ajax 处理回调
     * @property    ajaxCallback
     * @type    function
     * @default null
     * @static
     * @example
            $(document).ready( function(){
                UXC.Tab.ajaxCallback =
                    function( _data, _label, _container, _textStatus, _jqXHR ){
                        _data && ( _data = $.parseJSON( _data ) );
                        if( _data && _data.errorno === 0 ){
                            _container.html( printf( '<h2>UXC.Tab.ajaxCallback</h2>{0}', _data.data ) );
                        }else{
                            Tab.isAjaxInited( _label, 0 );
                            _container.html( '<h2>内容加载失败!</h2>' );
                        }
                    };
            });
     */
    Tab.ajaxCallback = null;
    /**
     * ajax 请求是否添加随机参数 rnd, 以防止页面缓存的结果差异
     * @property    ajaxRandom
     * @type    bool
     * @default true
     * @static
     */
    Tab.ajaxRandom = true;
    /**
     * 判断一个 label 是否为 ajax
     * @method  isAjax
     * @static
     * @param   {selector}  _label
     * @return  {string|undefined}
     */
    Tab.isAjax =
        function( _label ){
            return $(_label).attr('tabajaxurl');
        };
    /**
     * 判断一个 ajax label 是否已经初始化过
     * <br /> 这个方法需要跟 Tab.isAjax 结合判断才更为准确
     * @method  isAjaxInited
     * @static
     * @param   {selector}  _label
     * @param   {bool}      _setter     如果 _setter 不为空, 则进行赋值
     * @example
        function tabactive( _evt, _container, _tabIns ){
            var _label = $(this);
            UXC.log( 'tab ', _evt.type, _label.html(), new Date().getTime() );
            if( UXC.Tab.isAjax( _label ) && ! UXC.Tab.isAjaxInited( _label ) ){
                _container.html( '<h2>内容加载中...</h2>' );
            }
        }
     */
    Tab.isAjaxInited =
        function( _label, _setter ){
            _setter != 'undefined' && ( $(_label).data('TabAjaxInited', _setter ) );
            return $(_label).data('TabAjaxInited');
        }

    Tab.prototype = {
        /**
         * Tab 内部初始化方法
         * @method  _init
         * @private
         */
        _init:
            function(){
                if( !this._model.layoutIsTab() ) return this;
                Tab.getInstance( this._model.layout(), this );
                this._view.init();

                var _triggerTarget = $(this._model.triggerTarget());
                _triggerTarget && _triggerTarget.length 
                && this._model.tablabel( _triggerTarget ) && _triggerTarget.trigger('click');

                return this;
            }    
        /**
         * 把 _label 设置为活动状态
         * @method active
         * @param   {selector}  _label
         */
        , active:
            function( _label ){
                var _ix;
                if( typeof _label == 'number' ) _ix = _label;
                else{
                    _label && $(_label).length && ( _ix = this._model.tabindex( _label ) );
                }

                typeof _ix != 'undefined' && ( this._view.active( _ix ) );
                return this;
            }
    }
    /**
     * Tab 数据模型类
     * @namespace UXC.Tab
     * @class Model
     * @constructor
     * @param   {selector|string}   _selector       要初始化的 Tab 选择器
     * @param   {selector|string}   _triggerTarget  初始完毕后要触发的 label
     */
    function Model( _selector, _triggerTarget ){
        /**
         * Tab 的主容器
         * @property    _layout
         * @type    selector
         * @private
         */
        this._layout = _selector;
        /**
         * Tab 初始完毕后要触发的label, 可选
         * @property    _triggerTarget
         * @type    selector
         * @private
         */
        this._triggerTarget = _triggerTarget;
        /**
         * Tab 的标签列表选择器
         * @property    _tablabels
         * @type    selector
         * @private
         */
        this._tablabels;
        /**
         * Tab 的内容列表选择器
         * @property    _tabcontainers
         * @type    selector
         * @private
         */
        this._tabcontainers;
        /**
         * 当前标签的所在索引位置
         * @property    currentIndex
         * @type    int
         */
        this.currentIndex;
        
        this._init();
    }
    
    Model.prototype = {
        /**
         * Tab Model 内部初始化方法
         * @method  _init
         * @private
         */
        _init:
            function(){
                if( !this.layoutIsTab() ) return;
                var _p = this, _re = /^\~[\s]+/g;

                if( _p.isFromChild( _p.layout().attr('tablabels') ) ){
                    this._tablabels = _p.layout().find( _p.layout().attr('tablabels').replace( _re, '' ) );
                }else{
                    this._tablabels = $( _p.layout().attr('tablabels') );
                }

                if( _p.isFromChild( _p.layout().attr('tabcontainers') ) ){
                    this._tabcontainers = _p.layout().find( _p.layout().attr('tabcontainers').replace( _re, '' ) );
                }else{
                    this._tabcontainers = $( _p.layout().attr('tabcontainers') );
                }

                this._tablabels.each( function(){ _p.tablabel( this, 1 ); } );
                this._tabcontainers.each( function(){ _p.tabcontent( this, 1 ); } );
                this._tablabels.each( function( _ix ){ _p.tabindex( this, _ix ); });

                return this;
            }
        /**
         * 判断是否从 layout 下查找内容
         */
        , isFromChild:
            function( _selector ){
                return /^\~/.test( $.trim( _selector ) );
            }
        /**
         * 获取 Tab 的主容器
         * @method  layout
         * @return  selector
         */
        , layout: function(){ return this._layout; }
        /**
         * 获取 Tab 所有 label 或 特定索引的 label
         * @method  tablabels
         * @param   {int}   _ix
         * @return  selector
         */
        , tablabels: function( _ix ){ 
            if( typeof _ix != 'undefined' ) return $( this._tablabels[_ix] );
            return this._tablabels; 
        }
        /**
         * 获取 Tab 所有内容container 或 特定索引的 container
         * @method  tabcontainers
         * @param   {int}   _ix
         * @return  selector
         */
        , tabcontainers: function( _ix ){ 
            if( typeof _ix != 'undefined' ) return $( this._tabcontainers[_ix] );
            return this._tabcontainers; 
        }
        /**
         * 获取初始化要触发的 label
         * @method  triggerTarget
         * @return  selector
         */
        , triggerTarget: function(){ return this._triggerTarget; }
        /**
         * 判断一个容器是否 符合 Tab 数据要求
         * @method  layoutIsTab
         * @return  bool
         */
        , layoutIsTab: function(){ return this.layout().attr('tablabels') && this.layout().attr('tabcontainers'); }
        /**
         * 获取 Tab 活动状态的 class
         * @method  activeClass
         * @return  string
         */
        , activeClass: function(){ return this.layout().attr('tabactiveclass') || Tab.activeClass; }
        /**
         * 获取 Tab label 的触发事件名称
         * @method  activeEvent
         * @return  string
         */
        , activeEvent: function(){ return this.layout().attr('tabactiveevent') || Tab.activeEvent; }
        /**
         * 判断 label 是否符合要求, 或者设置一个 label为符合要求
         * @method  tablabel
         * @param   {bool}  _setter
         * @return  bool
         */
        , tablabel: 
            function( _label, _setter ){
                _label && ( _label = $( _label ) );
                if( !( _label && _label.length ) ) return;
                typeof _setter != 'undefined' && _label.data( 'TabLabel', _setter );
                return _label.data( 'TabLabel' );
            }
        /**
         * 判断 container 是否符合要求, 或者设置一个 container为符合要求
         * @method  tabcontent
         * @param   {selector}  _content
         * @param   {bool}      _setter
         * @return  bool
         */
        , tabcontent: 
            function( _content, _setter ){
                _content && ( _content = $( _content ) );
                if( !( _content && _content.length ) ) return;
                typeof _setter != 'undefined' && _content.data( 'TabContent', _setter );
                return _content.data( 'TabContent' );
            }
        /**
         * 获取或设置 label 的索引位置
         * @method  tabindex
         * @param   {selector}  _label
         * @param   {int}       _setter
         * @return  int
         */
        , tabindex: 
            function( _label, _setter ){
                _label && ( _label = $( _label ) );
                if( !( _label && _label.length ) ) return;
                typeof _setter != 'undefined' && _label.data( 'TabIndex', _setter );
                return _label.data( 'TabIndex' );
            }
        /**
         * 获取Tab label 触发事件后的回调
         * @method  tabactivecallback
         * @return  function
         */
        , tabactivecallback:
            function(){
                var _r;
                this.layout().attr('tabactivecallback') && ( _r = window[ this.layout().attr('tabactivecallback') ] );
                return _r;
            }
        /**
         * 获取 Tab label 变更后的回调
         * @method  tabchangecallback
         * @return  function
         */
        , tabchangecallback:
            function(){
                var _r;
                this.layout().attr('tabchangecallback') && ( _r = window[ this.layout().attr('tabchangecallback') ] );
                return _r;
            }
        /**
         * 获取 Tab label 活动状态显示样式的标签
         * @method  tablabelparent
         * @param   {selector}  _label
         * @return  selector
         */
        , tablabelparent:
            function( _label ){
                var _tmp;
                this.layout().attr('tablabelparent') 
                    && ( _tmp = _label.parent( this.layout().attr('tablabelparent') ) ) 
                    && _tmp.length && ( _label = _tmp );
                return _label;
            }
        /**
         * 获取 ajax label 的 URL
         * @method  tabajaxurl
         * @param   {selector}  _label
         * @return  string
         */
        , tabajaxurl: function( _label ){ return _label.attr('tabajaxurl'); }
        /**
         * 获取 ajax label 的请求方法 get/post
         * @method  tabajaxmethod
         * @param   {selector}  _label
         * @return  string
         */
        , tabajaxmethod: function( _label ){ return (_label.attr('tabajaxmethod') || 'get').toLowerCase(); }
        /**
         * 获取 ajax label 的请求数据
         * @method  tabajaxdata
         * @param   {selector}  _label
         * @return  object
         */
        , tabajaxdata: 
            function( _label ){ 
                var _r;
                _label.attr('tabajaxdata') && ( eval( '(_r = ' + _label.attr('tabajaxdata') + ')' ) );
                _r = _r || {};
                Tab.ajaxRandom && ( _r.rnd = new Date().getTime() );
                return _r;
            }
        /**
         * 获取 ajax label 请求URL后的回调
         * @method  tabajaxcallback
         * @param   {selector}  _label
         * @return  function
         */
        , tabajaxcallback: 
            function( _label ){ 
                var _r = Tab.ajaxCallback, _tmp;
                _label.attr('tabajaxcallback') && ( _tmp = window[ _label.attr('tabajaxcallback') ] ) && ( _r = _tmp );
                return _r;
            }
    };
    /**
     * Tab 视图模型类
     * @namespace UXC.Tab
     * @class View
     * @constructor
     * @param   {UXC.Tab.Model}   _model   
     */
    function View( _model ){
        /**
         * Tab 数据模型类实例引用 
         * @property    _model
         * @type {UXC.Tab.Model} 
         * @private
         */
        this._model = _model;
    }
    
    View.prototype = {
        /**
         * Tab 视图类初始化方法
         * @method  init
         */
        init:
            function() {
                UXC.log( 'Tab.View:', new Date().getTime() );
                var _p = this;
                this._model.tablabels().on( this._model.activeEvent(), function( _evt ){
                    var _sp = $(this), _r;
                    if( typeof _p._model.currentIndex !== 'undefined' 
                        && _p._model.currentIndex === _p._model.tabindex( _sp ) ) return;
                    _p._model.currentIndex = _p._model.tabindex( _sp );

                    _p._model.tabactivecallback() 
                        && ( _r = _p._model.tabactivecallback().call( this, _evt, _p._model.tabcontainers( _p._model.currentIndex ), _p ) );
                    if( _r === false ) return;
                    _p.active( _p._model.tabindex( _sp ) );
                });

                return this;
            }
        /**
         * 设置特定索引位置的 label 为活动状态
         * @method  active
         * @param   {int}   _ix
         */
        , active:
            function( _ix ){
                if( typeof _ix == 'undefined' ) return;
                var _p = this, _r, _activeClass = _p._model.activeClass(), _activeItem = _p._model.tablabels( _ix );
                _p._model.tablabels().each( function(){
                    _p._model.tablabelparent( $(this) ).removeClass( _activeClass );
                });
                _activeItem = _p._model.tablabelparent( _activeItem );
                _activeItem.addClass( _activeClass );

                _p._model.tabcontainers().hide();
                _p._model.tabcontainers( _ix ).show();

                _p._model.tabchangecallback() 
                    && ( _r = _p._model.tabchangecallback().call( _p._model.tablabels( _ix ), _p._model.tabcontainers( _ix ), _p ) );
                if( _r === false ) return;

                _p.activeAjax( _ix );
            }
        /**
         * 请求特定索引位置的 ajax tab 数据
         * @method  activeAjax
         * @param   {int}   _ix
         */
        , activeAjax:
            function( _ix ){
                var _p = this, _label = _p._model.tablabels( _ix );
                if( !Tab.isAjax( _label ) ) return;
                if( Tab.isAjaxInited( _label ) ) return;
                var _url = _p._model.tabajaxurl( _label );
                if( !_url ) return;

                UXC.log( _p._model.tabajaxmethod( _label )
                        , _p._model.tabajaxdata( _label )
                        , _p._model.tabajaxcallback( _label )
                        );

                Tab.isAjaxInited( _label, 1 );
                $[ _p._model.tabajaxmethod( _label ) ]( _url, _p._model.tabajaxdata( _label ), function( _r, _textStatus, _jqXHR ){

                     _p._model.tabajaxcallback( _label ) 
                        && _p._model.tabajaxcallback( _label )( _r, _label, _p._model.tabcontainers( _ix ), _p, _textStatus, _jqXHR );

                    !_p._model.tabajaxcallback( _label ) && _p._model.tabcontainers( _ix ).html( _r );
                });
            }
    };
    /**
     * 自动化初始 Tab 实例
     * 如果 Tab.autoInit = true, 鼠标移至 Tab 后会自动初始化 Tab
     */
    $(document).delegate( '.js_autoTab', 'mouseover', function( _evt ){
        if( !Tab.autoInit ) return;
        var _p = $(this), _tab, _src = _evt.target || _evt.srcElement;
        if( Tab.getInstance( _p ) ) return;
        _src && ( _src = $(_src) );
        UXC.log( new Date().getTime(), _src.prop('nodeName') );
        _tab = new Tab( _p, _src );
    });

}(jQuery));