这是一款效果非常酷的jQuery和css3全屏翻页切换页面特效插件。该插件是在BookBlock可预览的css3+js翻书效果的基础上,添加了侧边栏,和前后翻页按钮制作而成的。在插件中我们还集成了 jScrollPane 用来自定义滚动条元素。
下面的jQuery插件将在该插件中被使用:
HTML结构
.container作为wrapper。在里面,使用一个div .menu-panel作为侧边栏。“书本”使用.bb-custom-wrapper包裹起来。
<div id="container" class="container"> <div class="menu-panel"> <h3>Table of Contents</h3> <ul id="menu-toc" class="menu-toc"> <li class="menu-toc-current"><a href="#item1">Self-destruction</a></li> <li><a href="#item2">Why we die</a></li> <li><a href="#item3">The honeymoon</a></li> <li><a href="#item4">A drawing joke</a></li> <li><a href="#item5">Commencing practice</a></li> </ul> </div> <div class="bb-custom-wrapper"> <div id="bb-bookblock" class="bb-bookblock"> <div class="bb-item" id="item1"> <div class="content"> <div class="scroller"> <h2>Self-destruction</h2> <p>...</p> </div> </div><!-- /content --> </div><!-- /bb-item --> <div class="bb-item" id="item2"><!-- ... --></div> <div class="bb-item" id="item3"><!-- ... --></div> <div class="bb-item" id="item4"><!-- ... --></div> <div class="bb-item" id="item5"><!-- ... --></div> </div><!-- /bb-bookblock --> <nav> <a id="bb-nav-prev" href="#">←</a> <a id="bb-nav-next" href="#">→</a> </nav> <span id="tblcontents" class="menu-button">Table of Contents</span> </div><!-- /bb-custom-wrapper --> </div><!-- /container -->
JAVASCRIPT
我们需要指定每次翻页之后,当前项的index和jScrollPane 的状态,这些通过onEndFlip 在BookBlock的回调中指定:
var $container = $( '#container' ), // the element we will apply the BookBlock plugin to $bookBlock = $( '#bb-bookblock' ), // the BookBlock items (bb-item) $items = $bookBlock.children(), // index of the current item current = 0, // initialize the BookBlock bb = $( '#bb-bookblock' ).bookblock( { speed : 800, perspective : 2000, shadowSides : 0.8, shadowFlip : 0.4, // after each flip... onEndFlip : function(old, page, isLimit) { // update the current value current = page; // update the selected item of the table of contents (TOC) updateTOC(); // show and/or hide the navigation arrows updateNavigation( isLimit ); // initialize the jScrollPane on the content div for the new item setJSP( 'init' ); // destroy jScrollPane on the content div for the old item setJSP( 'destroy', old ); } } ), // the navigation arrows $navNext = $( '#bb-nav-next' ), $navPrev = $( '#bb-nav-prev' ).hide(), // the table of content items $menuItems = $container.find( 'ul.menu-toc > li' ), // button to open the TOC $tblcontents = $( '#tblcontents' ), transEndEventNames = { 'WebkitTransition': 'webkitTransitionEnd', 'MozTransition': 'transitionend', 'OTransition': 'oTransitionEnd', 'msTransition': 'MSTransitionEnd', 'transition': 'transitionend' }, // transition event name transEndEventName = transEndEventNames[Modernizr.prefixed('transition')], // check if transitions are supported supportTransitions = Modernizr.csstransitions;
在元素初始化时为它们绑定一些事件,同时我们需要初始化jScrollPane 的当前项。
function init() { // initialize jScrollPane on the content div of the first item setJSP( 'init' ); initEvents(); }
因为我们最终需要初始化和销毁jScrollPane,因此,可以定义一个函数来做这些事情。
function setJSP( action, idx ) { var idx = idx === undefined ? current : idx, $content = $items.eq( idx ).children( 'div.content' ), apiJSP = $content.data( 'jsp' ); if( action === 'init' && apiJSP === undefined ) { $content.jScrollPane({verticalGutter : 0, hideFocus : true }); } else if( action === 'reinit' && apiJSP !== undefined ) { apiJSP.reinitialise(); } else if( action === 'destroy' && apiJSP !== undefined ) { apiJSP.destroy(); } }
我们需要绑定一些事件:
- 1、当我们点击前后翻页导航按钮时,我们需要调用BookBlock的next() 和 prev()方法。
- 2、当我们点击侧边栏按钮时,侧边栏将被显示/隐藏。
- 3、当我们点击侧边栏选项时,将调用BookBlock的jump()方法。
- 4、jScrollPane将在窗口变化时被重置。
function initEvents() { // add navigation events $navNext.on( 'click', function() { bb.next(); return false; } ); $navPrev.on( 'click', function() { bb.prev(); return false; } ); // add swipe events $items.on( { 'swipeleft' : function( event ) { if( $container.data( 'opened' ) ) { return false; } bb.next(); return false; }, 'swiperight' : function( event ) { if( $container.data( 'opened' ) ) { return false; } bb.prev(); return false; } } ); // show TOC $tblcontents.on( 'click', toggleTOC ); // click a menu item $menuItems.on( 'click', function() { var $el = $( this ), idx = $el.index(), jump = function() { bb.jump( idx + 1 ); }; current !== idx ? closeTOC( jump ) : closeTOC(); return false; } ); // reinit jScrollPane on window resize $( window ).on( 'debouncedresize', function() { // reinitialise jScrollPane on the content div setJSP( 'reinit' ); } ); }
前后翻页导航按钮的可见性将依赖与当前页面。如果我们是在第一页,则向前翻页导航按钮不可见。如果是在最后一页,则向后翻页导航按钮不可见。
function updateNavigation( isLastPage ) { if( current === 0 ) { $navNext.show(); $navPrev.hide(); } else if( isLastPage ) { $navNext.hide(); $navPrev.show(); } else { $navNext.show(); $navPrev.show(); } }
当我们打开侧边栏时,要隐藏前后翻页导航按钮,关闭侧边栏时在重新显示它们。
我们将使用CSS transition来制作侧边栏的动画效果。如果浏览器不支持CSS transition,那么这里只是简单的显示和隐藏侧边栏菜单。
function toggleTOC() { var opened = $container.data( 'opened' ); opened ? closeTOC() : openTOC(); } function openTOC() { $navNext.hide(); $navPrev.hide(); $container.addClass( 'slideRight' ).data( 'opened', true ); } function closeTOC( callback ) { $navNext.show(); $navPrev.show(); $container.removeClass( 'slideRight' ).data( 'opened', false ); if( callback ) { if( supportTransitions ) { $container.on( transEndEventName, function() { $( this ).off( transEndEventName ); callback.call(); } ); } else { callback.call(); } } }