mass Framework switchable插件


最近都忙着寫這個插件,用它來統合跑馬燈(marquee),輪播(carousel),風手琴(accordion), 切換卡(tabs), slide(幻燈片)這五種控件。

下面是它們的一些描述:

  • 跑馬燈沒有觸發點(trigger),而顯示內容通常是一行行文字或扁平狀的圖片,自動往上往下滾動。不過也有從左到右滾動的。
  • 輪播經常出現新聞的首頁,觸發點與面板個數相同,基本上從左到右切換,到了盡頭回到第一張繼續切換。觸發點都浮於控件的最上層的右下角。
  • 風手琴與輪播很相似,不過很少會自動進行自動切換。其觸發器與控件同寬或同高,非常顯眼。
  • 切換卡的觸發器會於控件的上方,也比較少自動切換。
  • 幻燈片基本會提供兩個觸發點,上一頁與下一頁,還有綁定鍵盤事件進行上下翻。

因此,我們要提供一個API,用於讓用戶切換到指定的面板,同時讓對應的觸發點處於激活狀態(高亮狀態)。

另外此五個控件就只在HTML結構上存在出入,什么功能只是添多或添少的問題而已。因此我提供了兩種方案來指定控件的主體。一種是像EXT那樣,其HTML與CSS都是動態生成的,另一種是,指定頁面已有的某一HTML片段作為頁面的主體。然后再從這主體中抽取出觸發點(triggers)與面板(panels),轉化為控件實例的屬性,供其他API調用。

下面是其API的說明:

$.fn.switchable(settings)

settings的配置參數:

  • data:用於創建控件,必須是一個對象數組,每個對象都擁有trigger(可選)與panel屬性。
  • data_expr:頁面現存的具有切換卡,手風琴等結構的HTML元素的CSS表達式。此屬性與data屬性只能二選一。
  • trigger_class:觸發器的類名,它起着類似按鈕的作用,用於切換面板。
  • panel_class:面板的類名。
  • active_class:處於激活狀態的面板與觸發器都會添加上此類名。
  • active_event:用於切換面板的事件,不是click就是mouseover。
  • active_callback:切換面板時的回調函數。
  • autoplay:是否自動進行切換,默認是false。
  • pause_over_panel:當鼠標移到控件之上是否中止切換,默認是false。
  • interval:切換面板后要延遲多久才自動開始下一個切換,單位為ms,默認是1000。
  • switch_out:正在處於激活狀態的面板在失去激活狀態時要進行的切換動畫,默認是$.fn.slideUp。
  • switch_out_args:上面動畫的參數, 默認為500。
  • switch_in:某一面板在變成激活狀態時要進行的切換動畫,默認是$.fn.slideDown。
  • switch_in_args:上面動畫的參數, 默認為500。

切換卡對象默認擁有以下方法,都是使用$(expr).tabs(method,args1,args2,args3)的形式進行調用:

  • active(index, [callback],[e]): 切換到某一面板,index為面板的序號,從零開始。callback為回調函數,e為事件對象。回調函數中的this指向事件源對象或ui.target[0], 參數為e或ui
  • remove(index, [callback]): 移除到某一面板,index為面板的序號,從零開始。callback為回調函數,擁有一個參數,就是實例自身, this指向ui.target[0]。
  • add(index, trigger, panel): 在某一切換卡之后添加一個切換卡,trigger與panel為新切換卡的按鈕與面板。
  • destroy(): 銷毀切換卡實例,移除相關事件綁定。
  • invoke(method, args1, args2): 如果method為實例的一個方法,則調用此方法,將其他參數傳進去,否則則重寫或添加相關屬性。

經過我的觀察與研究,無論是切換卡也好,輪播也好,幻燈片也好,它們的結構都是非常相似。其中用於裝載內容的面板panel是必不可少, 而在這些控件中,基本上都會一個觸發器(trigger)與之對應,另外,在輪播控件中,切換大多數是整體向左移動或整體向上移動,這就要求有一個容器, 其寬等於所有面板的寬或其高等於所有面板的高,因此網上許多輪播控件都采用dl,dt,dd結構,對應我的switchable控件,分別中ui.target, ui.triggers, ui.panels,其中ui是可切換對象的實例,默認類名依次是.mass_swichable, .trigger, .panel。那么對非輪播控件,ui.target在外觀的構建上也不是沒有用處的, 畢竟多一層元素,我們可以用CSS把控件打扮得更漂亮。

下面是一個典型可切換對象的HTML結構

        <div class="sample">
            <div class="mass_switchable">
                <div class="trigger active">標題1</div>
                <div class="panel active">面板1</div>
                <div class="trigger">標題2</div>
                <div class="panel">面板2</div>
                <div class="trigger">標題3</div>
                <div class="panel">面板3</div>
                <div class="trigger">標題4</div>
                <div class="panel">面板4</div>
            </div>
        </div>
        

默認情況下,控件會在ui.parent進行事件代理(代理trigger元素上的點擊事件或mouseover事件),以實現面板的切換。 至於這些面板怎么切換,控件提供了三個入口, switch_in回調(this指向正要變成激活狀態的面板), switch_out回調(this指向正要失去激活狀態的面板)與 active_callback回調(this指向可切換對象, 我們可以ui.active_index得知處於激活狀態的面板的索引值, 同時也是對應觸發點的索引值)

下面是一些例子, 更詳細的講解見github上的文檔!暫沒有幻燈片的示例,其實它是最簡單的,但通常是炫在其幻換時的特效,大家可以想象一下微軟的PowerPoint,因此這需要一個強大的切換特效插件才行。這個以后會補上的。

http://detail.tmall.com/item.htm?spm=1103qB9o.2-v9_S.s-3vAY2l&id=12473871046 http://www.madeincima.it/download/samples/jquery/easyAccordion/
切換卡
            .tabs {
                border:20px solid #E9EDF1;
                position:relative;
                width:400px;
                height:200px;
                background:#fff url(tabs_header.jpg) left top no-repeat;
                overflow:hidden;
            }
            .tabs .trigger{
                float:left;
                height:40px;
                line-height:40px;
                margin-left:30px;
                width:50px;
                text-align:center;
                cursor: pointer;
                color:#fff;
                font-weight:700;
            }
            .tabs .trigger.active{
                color:yellow;
            }
            .tabs .panel{
                position:absolute;
                display:none;
                top:40px;
                left:0px;
                width:398px;
                height:150px;
                background:#fff;
                color: #000;
                border:1px solid #595A5A;
                border-radius: 4px 4px 4px 4px;
                box-shadow: 5px 1px 3px  #8493A6;
            }
            .tabs .panel.active{
                display:block;
            }
            .tabs .panel div{
                margin:20px;
            }
            
            $.require("ready,more/switchable",function(){
                $(".tabs").switchable({
                    data: "1234".split("").map(function(el, i){
                        return {
                            trigger:"標題"+ (i+1),
                            panel:"<div>面板"+(i+1)+"</div>"
                        }
                    }),
                    switch_in: function(){
                        this.show();
                    },
                    switch_out: function(){
                        this.hide();
                    }
                });
            })
            
垂直手風琴
.starfish  {
    background:#DCDCDC;
    width: 620px;
    height:245px;
    overflow:hidden;
}
.starfish .trigger{
    height: 30px;
    width: 600px;
    background: url(mass_accordion_trigger.jpg) no-repeat top right #a9d06a;
    padding: 0 10px 0 10px;
    line-height: 30px;
    color: #fff;
    font-size: 12px;
    color: #000;
    border-bottom: 1px solid #cde99f;
    cursor: pointer;
}
.starfish .trigger.active{
    background: url(mass_accordion_trigger_active.jpg) no-repeat top right #e0542f;
    color: #fff;
    border-bottom: 1px solid #f68263;
}
.starfish .panel {
    width: 600px;
    height: 100px;
    padding: 5px 10px 15px 10px;
    color: #444;
    display:none;
    overflow: hidden;
}
            
            $.require("ready,more/switchable",function(){
               $(".starfish").switchable({
                    data:[
                        {trigger:"標題1",panel:"這是一個簡單的垂直手風琴"},
                        {trigger:"標題2",panel:"只有最基本的功能"},
                        {trigger:"標題3",panel:"<div class=content>面板3</div>"},
                        {trigger:"標題4",panel:"<div class=content>面板4</div>"}
                    ],
                    switch_in: $.fn.slideDown,
                    switch_out: $.fn.slideUp
                });
            })
            
水平手風琴
.elephant{
    width:600px;
    height:195px;
    padding:30px;
    background:#fff;
    border:1px solid #b5c9e8;
    position:relative;
    overflow:hidden;
}
/* 這里要足夠寬,能裝下四個trigger與一個panel!*/
.elephant .mass_switchable{
    width:900px;
    height:180px;
}
.elephant .trigger{
    float:left;
    width:56px;
    height:180px;
    font-size:14px;
    font-weight:bold;
    background:#fff url(elephant_trigger.jpg) 0 0 no-repeat;
    color:#26526c;
    cursor:pointer;
}
/* 讓字體垂直顯示*/
.elephant .trigger span{
    margin-left:20px;
    margin-top:20px;
    width:14px;
    display:block;
    height:140px;
    color:#000;
    letter-spacing:1px;
    word-spacing:0;
    text-align:right;
}
.elephant .trigger.active{
    cursor:pointer;
    background:#fff url(elephant_active.jpg) 0 0 no-repeat
}
.elephant .trigger.active span{
    color:#fff;
}

.elephant .panel{
    float:left;
    padding:25px;
    width:320px;
    height:130px;
    border:1px solid #dbe9ea;
    border-left:0;
    margin-right:3px;
}
.elephant  .panel h2{
    font-size:25px;
    margin-top:10px;
    margin-bottom:10px;
    font-family:serif;
    color:#294F88;
}
.elephant  .panel  p{
    font-family:serif;
    font-size:14px;
    line-height:17px;
    color:#294F88;
}
/* 裝飾用*/
.elephant .panel img{
    float:right;
    margin:0 0 0 20px;
    position:relative;
    top:-20px
}
            
            $.require("ready,more/switchable",function(){
                var elephant = $(".elephant").switchable({
                    data:[
                        {
                            trigger:"<span>第一張</span>",
                            panel:'<h2>First mammoth here</h2><p><img src="elephant0.png" />Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean commodo ligula eget dolor.</p>'
                        },
                        {
                            trigger:"<span>第二張</span>",
                            panel:'<h2>Over the moon!</h2><p><img src="elephant1.png"  />Aenean commodo ligula eget dolor. Aenean massa. Nascetur aenean commodo ligula eget dolor. Aenean massa eget. </p>'
                        },
                        {
                            trigger:"<span>第三張</span>",
                            panel:'<h2>Another mammoth</h2><p><img src="elephant2.png" />Ipsum dolor sit amet.Aenean ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur.</p>'
                        },
                        {
                            trigger:"<span>第四張</span>",
                            panel: '<h2>This is my favourite</h2><p><img src="elephant3.png"  />Cum sociis natoque penatibus et donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim.</p>'
                        }
                    ],
                    switch_in: function(){
                        this.fx(600,{
                            width:"show",
                            paddigLeft:"show",
                            paddingRight:"show"})
                    },
                    switch_out: function(){
                        this.fx(600,{
                            width:"hide",
                            paddigLeft:"hide",
                            paddingRight:"hide"})
                    }
                }).switchable("getUI")
                elephant.target.width( elephant.panels.innerWidth()+ elephant.triggers.innerWidth() * 5 );
                elephant.panels.not(".active").fx(10,{
                    width:"hide",
                    paddigLeft:"hide",
                    paddingRight:"hide"
                });
            })
            
水平輪播

鼠標移到控件之上會出現上一頁與下一頁。

.winnower {
    width:536px;
    height:265px;
    position:relative;
    overflow:hidden;
    border:2px solid #000;
}
.winnower .mass_switchable{
    width:3000px;/*此寬可容納所有面板*/
    height:270px;
}
/* 平鋪所有面板,實現整體往左移或往右移*/
.winnower .panel{
    float:left;
    display:block;
}
/* 設置觸發點*/
.winnower .trigger{
    position:absolute;
    display: block;
    width:15px;
    height:15px;
    z-index:100;
    bottom: 20px;
}
/* 灰色的圓點 */
.winnower .trigger a {
    display:block;
    width:15px;
    height:15px;
    text-decoration:none;
    outline:none;
    background: url("winnower_s.png") no-repeat 3px -12px transparent;
}
/* 橙色的圓點 */
.winnower .trigger a:hover,.winnower .trigger.active a{
    background-position:-15px -12px;
}
/*上一個與下一個*/
.winnower .arrow{
    position:absolute;
    display:none;
    z-index:100;
    width:25px;
    height:40px;
    top:125px;
    background: url("winnower_s.png") no-repeat scroll -40px 0px transparent;
}
.winnower .prev{
    left:5px;
}
.winnower .next{
    background: url("winnower_s.png") no-repeat scroll -90px 0px transparent;
    right:5px;
}
            
            $.require("ready,more/switchable",function(){
               var winnower = $(".winnower").switchable({
                    data: "01234".split("").map(function(el,d){
                        return {
                            trigger:'<a href="javascript:void(0)"></a>',
                            panel:'<div><img src="winnower'+d+'.jpg" /></div>'
                        };
                    }),
                    active_callback: function(){
                        var w = -1 * this.panels.innerWidth() * this.active_index;
                        this.target.fx(500, {"margin-left":w }  )
                    }
                }).switchable("getUI");
                /* 調整觸發器的位置,向它位於控件的左下角水平排列 */
                winnower.triggers.each(function(el, i){
                    $(el).css( "right", 100 - i * 17);
                });
                /* 生成上一頁與下一頁按鈕 */
                var winnowerUI = winnower.parent.append('<div class="next arrow" ></div>').append('<div class="prev arrow"></div>')
                var winnowerArrow = winnowerUI.find(".arrow");

                winnowerUI.mouseenter(function(){
                    winnowerArrow.show()
                }).mouseleave(function(){
                    winnowerArrow.hide()
                });
                winnowerArrow.click(function(){
                    var next = $(this).hasClass("next");
                    var length = winnower.triggers.length-1
                    var i = winnower.active_index ;
                    if(next){
                        var index =  i+1 > length ? 0 : i+1;
                    }else{
                        index = i-1 < 0 ? length : i-1;
                    }
                    winnower.active( index, winnower.active_callback )
                });
            })
            
以縮略圖作為觸發器的水平輪播
.imac{
    width:640px;
    height:545px;
    overflow:hidden;
    border:2px solid #5296c7;
}
.imac .panel{
    float:left;
    width:640px;
    height:480px;
    display:block;
}
.imac .trigger{
    display:inline-block;
    margin-top:10px;
    margin-right:10px;
}
.imac .trigger img{
    display:inline-block;
    border:1px solid #9cf;
}
.imac .trigger.active img,  .imac .trigger img:hover{
    border: 1px solid #369;
}
/* 讓所有觸發器居中對齊 */
.imac center {
    width:640px;
}
            
            $.require("ready,more/switchable",function(){
               var imac = $(".imac").switchable({
                    data: "0123456".split("").map(function(el,d){
                        return {
                            trigger:'<img src="imac'+d+'.jpg" width=50 height=46 />',
                            panel:'<img src="imac'+d+'.jpg" />'
                        }
                    }),
                    active_callback: function(){
                        var w = -1 * this.panels.innerWidth() * this.active_index;
                        this.target.fx(500, {"margin-left":w }  )
                    }
                }).switchable("getUI");
                imac.target.width(imac.panels.innerWidth() * 7 );
                $("<center></center>").appendTo(".imac").append(imac.triggers);
            })
            
通過淡入淡出進行切換的水平輪播
.fade{
    position:relative;
    width:478px;
    height:286px;
    border:1px solid #666;
    overflow:hidden;
}
.fade .panel{
    position:absolute;
}
.fade .triggers{
    position:absolute;
    bottom:0;
    background:#000;
    height:30px;
    width:478px;
    filter: Alpha(Opacity=30);
    opacity:0.3;
    z-index:10;
    cursor:pointer;
}
.fade .trigger {
    position:absolute;
    width:20px;
    height:20px;
    bottom: 5px;
    z-index:100;
}
.fade .trigger a{
    width:20px;
    height:20px;
    text-align:center;
    line-height:20px;
    display:inline-block;
    color:#FFF;
    border:#e5eaff 1px solid;
    background:#6f4f67;
    filter: Alpha(Opacity=80);
    opacity:0.8;
    text-decoration:none;
    cursor:pointer
}
.fade .trigger a:hover, .fade .trigger.active a{
    background:#900;
}
            
            $.require("ready,more/switchable",function(){
               var fade = $(".fade").switchable({
                    data: "0123".split("").map(function(el,d){
                        return {
                            panel:'<img src="fade'+d+'.jpg" />',
                            trigger:'<a href="javascript:void(0)">'+(d+1)+"</a>"
                        }
                    }),
                    switch_in: function(){
                        this.fx(600,{o:1})
                    },
                    switch_out: function(){
                        this.fx(600,{o:0})
                    },
                    interval:2000,
                    autoplay: true,
                    pause_over_panel:true
                }).switchable("getUI");
                $("<div class=triggers></div>").appendTo(fade.target);

                fade.triggers.each(function(el, i){
                    if( i != 0){
                        fade.panels.eq(i).css("opacity",0)
                    }
                    $(el).css("right",90- i * 24)
                });
            });
            
觸發器與面板一體化的手風琴
.dew {
    position:relative;
    width:500px;
    height:200px;
    overflow:hidden;
}
.dew .panel{
    position:absolute;
}
            
            $.require("ready,more/switchable",function(){
                var dew = $(".dew").switchable({
                    data:"012345".split("").map(function(el,d){
                        return {
                            panel:'<div><img src="../public/styles/switchable/dew'+d+'.jpg" /></div>'
                        }
                    }),
                    count:0
                }).switchable("getUI");

                function switchIt(e){
                    var index = $(this).index();
                    var width = $(this).width();
                    dew.panels.each(function(el,i){
                        $(el).fx(500,{
                            left:i * 36+( i > index ? width - 36: 0),
                            after:function(){
                                dew.count += 1;
                                if(dew.count == 6){
                                    dew.count = 0
                                    setTimeout(function(){
                                        dew.panels.one("mouseover",switchIt);
                                    },300);
                                }
                            }
                        })
                    });
                }

                dew.panels.each(function(el, i){
                    $(el).css("left", i * 83);
                }).one("mouseover",switchIt);

                dew.target.mouseleave(function(){
                    dew.panels.each(function(el, i){
                        $(el).fx(500,{
                            left: i * 83
                        });
                    });
                });
            });
            
水平跑馬燈
          .news{
                width:200px;
                height:24px;
                border:1px solid black;
                position:relative;
                overflow:hidden;
            }
            .news .panel{
                position:absolute;
                top: 5px;
                width:150px;
            }
            


            $.require("ready,more/switchable",function( ){
                var news = $(".news").switchable({
                    data:[
                        {panel :'<span style="color:red">這是第一條新聞</span>'},
                        {panel :'<span style="color:blue">這是第二條新聞</span>'},
                        {panel :'<span style="color:#9932CC">這是第三條新聞</span>'},
                    ],
                    autoplay:true,
                    pause_over_panel: true,
                    interval:2200,
                    active_callback:function(i){
                        this.panels.fx(2000, {
                            "left": "-=150",
                            after:function(){
                                if($(this).hasClass("active")){
                                    $(this).css("left",300);
                                }
                            }
                        })
                    }
                }).switchable("getUI");
                news.panels.each(function(el,i){
                    $(this).css( "left", 150 * i );
                });
            })
            


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM