isotope自动布局

HTML5应用开发:神奇的动态布局库isotope教程

1. isotope介绍

Isotope 是一个jQuery的插件,用来实现精美的动态元素布局。可以到http://isotope.metafizzy.co/demos/elements-complete.html了解一下大概情况。

Isotope可以实现仅仅依靠CSS3无法实现的动态布局方式,可以动态添加,删除,排序,筛选元素。Isotope的动画引擎可以充分使用现代浏览器CSS动画中GPU硬件加速性能,。

实例我已经上传到CSDN资源中,敬请下载。

2. 简单的isotope例子

Isotope要求jQuery1.4.3版本以上。首先需要在HTML页面中加载jQuery和isotope。


  1. "../js/jquery-1.7.1.min.js">  
  2. "../jquery.isotope.min.js">  


Isotope可以工作在一个包含很多类似item的container中,如下面所示:在div container中,声明了很累类似的div item。.


  1. "container">  
  2.   class="item">...
  
  •   class="item">...
  •   
  •   class="item">...
  •   
  •   ...  
  •   



    在JavaScript中,添加如下代码:


    1. $('#container').isotope({  
    2.   // options  
    3.   itemSelector : '.item',  
    4.   layoutMode : 'fitRows'  
    5. });  



    itemSelector 用来指定container中用来动态排版的元素。


    运行效果如下图所示:

    调整窗口大小后,排列效果图。

     

    3. Sorting and Filtering

    在isotope中,可以动态地对元素进行排序和筛选。

    排序的方式很多样化,可以按照元素的不同属性进行排序。首先在HTML页面中添加相应的option:


    1. "options" class="clearfix">  
    2.     

      Sort

        
    3.      "sort-by" class="option-set clearfix" data-option-key="sortBy">  
    4.       
    5. "#sortBy=original-order" data-option-value="original-order" class="selected" data>original-order
    6.   
    7.       
    8. "#sortBy=name" data-option-value="name">name
    9.   
    10.       
    11. "#sortBy=symbol" data-option-value="symbol">symbol
    12.   
    13.       
    14. "#sortBy=number" data-option-value="number">number
    15.   
    16.       
    17. "#sortBy=weight"  data-option-value="weight">weight
    18.   
    19.       
    20. "#sortBy=category" data-option-value="category">category
    21.   
    22.       
    23. "#sortBy=random" data-option-value="random">random
    24.   
    25.       
    26.     

      Sort direction

        
    27.     "sort-direction" class="option-set clearfix" data-option-key="sortAscending">  
    28.       
    29. "#sortAscending=true" data-option-value="true" class="selected">sort ascending
    30.   
    31.       
    32. "#sortAscending=false" data-option-value="false">sort descending
    33.   
    34.       
    35.      



    我们看到,排序的方式包含了element所有的属性。可以进行升序排列也可以降序排列。

    Element代码:


    1. class="element transition metal   " data-symbol="Hg" data-category="transition">  
    2.   class="number">80

        
    3.   class="symbol">Hg  
    4.   class="name">Mercury  
    5.   class="weight">200.59

        
      



    在JavaScript中,对每个sorting的方法进行实现:


    1. $(function(){  
    2.   var $container = $('#container');  
    3.   $container.isotope({  
    4.     itemSelector : '.element',  
    5.     getSortData : {  
    6.       symbol : function( $elem ) {  
    7.         return $elem.attr('data-symbol');  
    8.       },  
    9.       category : function( $elem ) {  
    10.         return $elem.attr('data-category');  
    11.       },  
    12.       number : function( $elem ) {  
    13.         return parseInt( $elem.find('.number').text(), 10 );  
    14.       },  
    15.       weight : function( $elem ) {  
    16.         return parseFloat( $elem.find('.weight').text().replace( /[\(\)]/g, '') );  
    17.       },  
    18.       name : function ( $elem ) {  
    19.         return $elem.find('.name').text();  
    20.       }  
    21.     }  
    22.   });  
    23.     
    24.   var $optionSets = $('#options .option-set'),  
    25.       $optionLinks = $optionSets.find('a');  
    26.   $optionLinks.click(function(){  
    27.     var $this = $(this);  
    28.     // don't proceed if already selected  
    29.     if ( $this.hasClass('selected') ) {  
    30.       return false;  
    31.     }  
    32.     var $optionSet = $this.parents('.option-set');  
    33.     $optionSet.find('.selected').removeClass('selected');  
    34.     $this.addClass('selected');  
    35.   
    36.     // make option object dynamically, i.e. { filter: '.my-filter-class' }  
    37.     var options = {},  
    38.         key = $optionSet.attr('data-option-key'),  
    39.         value = $this.attr('data-option-value');  
    40.     // parse 'false' as false boolean  
    41.     value = value === 'false' ? false : value;  
    42.     options[ key ] = value;  
    43.     if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {  
    44.       // changes in layout modes need extra logic  
    45.       changeLayoutMode( $this, options )  
    46.     } else {  
    47.       // otherwise, apply new options  
    48.       $container.isotope( options );  
    49.     }  
    50.       
    51.     return false;  
    52.   });  
    53. });  



    筛选的实现:isotope可以筛选不同属性的元素,需要对每个element属性通过class进行标记,如一个典型的element定义如下:

     
      
    1. class="element transition metal   " data-symbol="Hg" data-category="transition">  
    2.       class="number">80

        
    3.       class="symbol">Hg  
    4.       class="name">Mercury  
    5.       class="weight">200.59

        
    6.     
      

    在class中表明该元素是transition 而且是metal和
    sorting类似,在HTML中添加筛选的option:


    1. "options" class="clearfix">  
    2.      
    3.      
    4.      

      Filters

        
    5.   
    6.      "filters" class="option-set clearfix" data-option-key="filter">  
    7.        
    8. "#filter" data-option-value="*" class="selected">show all
    9.   
    10.        
    11. "#filter" data-option-value=".metal">metal
    12.   
    13.        
    14. "#filter" data-option-value=".transition">transition
    15.   
    16.        
    17. "#filter" data-option-value=".post-transition">post-transition
    18.   
    19.        
    20. "#filter" data-option-value=".nonmetal">nonmetal
    21.   
    22.        
    23. "#filter" data-option-value=".inner-transition">inner-transition
    24.   
    25.        
    26. "#filter" data-option-value=".alkali, .alkaline-earth">alkali and alkaline-earth
    27.   
    28.        
    29. "#filter" data-option-value=":not(.transition)">not transition
    30.   
    31.        
    32. "#filter" data-option-value=".metal:not(.transition)">metal but not transition
    33.   
    34.        
    35.     



    对应的JavaScript function实现如下:


    1. $(function(){  
    2.         
    3.       var $container = $('#container');  
    4.   
    5.       $container.isotope({  
    6.         itemSelector : '.element'  
    7.       });  
    8.         
    9.         
    10.       var $optionSets = $('#options .option-set'),  
    11.           $optionLinks = $optionSets.find('a');  
    12.   
    13.       $optionLinks.click(function(){  
    14.         var $this = $(this);  
    15.         // don't proceed if already selected  
    16.         if ( $this.hasClass('selected') ) {  
    17.           return false;  
    18.         }  
    19.         var $optionSet = $this.parents('.option-set');  
    20.         $optionSet.find('.selected').removeClass('selected');  
    21.         $this.addClass('selected');  
    22.     
    23.         // make option object dynamically, i.e. { filter: '.my-filter-class' }  
    24.         var options = {},  
    25.             key = $optionSet.attr('data-option-key'),  
    26.             value = $this.attr('data-option-value');  
    27.         // parse 'false' as false boolean  
    28.         value = value === 'false' ? false : value;  
    29.         options[ key ] = value;  
    30.         if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {  
    31.           // changes in layout modes need extra logic  
    32.           changeLayoutMode( $this, options )  
    33.         } else {  
    34.           // otherwise, apply new options  
    35.           $container.isotope( options );  
    36.         }  
    37.           
    38.         return false;  
    39.       });  
    40.   
    41.         
    42.     });  



    Filter demo演示,全部显示:

    筛选所有metal的元素:

     

    4. 动态添加元素

    在isotope中,可以对container中的元素进行动态的删除和添加。

    首先还是在HTML页面中添加相应的操作option:

     
      
    1. "options">  
    2.    class="clearfix">  
    3.      "insert">"#insert">Insert new elements
    4.   
    5.      "append">'#append'>Append new elements
    6.   
    7.      "prepend">'#prepend'>Prepend
    8.   
    9.      
    10.    

    在对应的JavaScript中,添加对function的实现:

       
    1. $(function(){  
    2.     
    3.   var $container = $('#container');  
    4.   
    5.     
    6.   $('#insert a').click(function(){  
    7.     var $newEls = $( fakeElement.getGroup() );  
    8.     $container.isotope( 'insert', $newEls );  
    9.   
    10.     return false;  
    11.   });  
    12.   
    13.   $('#append a').click(function(){  
    14.     var $newEls = $( fakeElement.getGroup() );  
    15.     $container.append( $newEls ).isotope( 'appended', $newEls );  
    16.   
    17.     return false;  
    18.   });  
    19.   
    20.   
    21.   $('#prepend a').click(function(){  
    22.     var $newEls = $( fakeElement.getGroup() );  
    23.     $container  
    24.       .prepend( $newEls ).isotope('reloadItems').isotope({ sortBy: 'original-order' })  
    25.       // set sort back to symbol for inserting  
    26.       .isotope('option', { sortBy: 'symbol' });  
    27.   
    28.     return false;  
    29.   });  
    30.   
    31.   $container.isotope({  
    32.     itemSelector : '.element',  
    33.     filter: '*',  
    34.     getSortData : {  
    35.       symbol : function( $elem ) {  
    36.         return $elem.attr('data-symbol');  
    37.       }  
    38.     },  
    39.     sortBy : 'symbol'  
    40.   });  
    41.   
    42. });  
       


    5. 不同的布局机制

    在本例中,我们来尝试isotope中非常神奇的布局机制。

    首先在HTML页面中,添加布局机制的选项:

    1. "options" class="clearfix">  
    2.     
    3.   

      Layout modes

        
    4.   
    5.   "layouts" class="option-set clearfix" data-option-key="layoutMode">  
    6.     
    7. "#masonry" data-option-value="masonry" class="selected">masonry
    8.   
    9.     
    10. "#fitRows" data-option-value="fitRows">fitRows
    11.   
    12.     
    13. "#cellsByRow" data-option-value="cellsByRow">cellsByRow
    14.   
    15.     
    16. "#straightDown" data-option-value="straightDown">straightDown
    17.   
    18.     
    19. "#masonryHorizontal" data-option-value="masonryHorizontal" class="horizontal">masonryHorizontal
    20.   
    21.     
    22. "#fitColumns" data-option-value="fitColumns" class="horizontal">fitColumns
    23.   
    24.     
    25. "#cellsByColumn" data-option-value="cellsByColumn" class="horizontal">cellsByColumn
    26.   
    27.     
    28. "#straightAcross" data-option-value="straightAcross" class="horizontal">straightAcross
    29.   
    30.     
    31.    

    在JavaScript代码中实现相应的布局机制:

      
    1. $(function(){  
    2.     
    3.   var $container = $('#container');  
    4.     
    5.     
    6.   // add randomish size classes  
    7.   $container.find('.element').each(function(){  
    8.     var $this = $(this),  
    9.         number = parseInt( $this.find('.number').text(), 10 );  
    10.     if ( number % 7 % 2 === 1 ) {  
    11.       $this.addClass('width2');  
    12.     }  
    13.     if ( number % 3 === 0 ) {  
    14.       $this.addClass('height2');  
    15.     }  
    16.   });  
    17.     
    18.   $container.isotope({  
    19.     itemSelector : '.element',  
    20.     masonry : {  
    21.       columnWidth : 120  
    22.     },  
    23.     masonryHorizontal : {  
    24.       rowHeight: 120  
    25.     },  
    26.     cellsByRow : {  
    27.       columnWidth : 240,  
    28.       rowHeight : 240  
    29.     },  
    30.     cellsByColumn : {  
    31.       columnWidth : 240,  
    32.       rowHeight : 240  
    33.     }  
    34.   });  
    35.     
    36.     
    37.   // change layout  
    38.   var isHorizontal = false;  
    39.   function changeLayoutMode( $link, options ) {  
    40.     var wasHorizontal = isHorizontal;  
    41.     isHorizontal = $link.hasClass('horizontal');  
    42.   
    43.     if ( wasHorizontal !== isHorizontal ) {  
    44.       // orientation change  
    45.       // need to do some clean up for transitions and sizes  
    46.       var style = isHorizontal ?   
    47.         { height: '80%', width: $container.width() } :   
    48.         { width: 'auto' };  
    49.       // stop any animation on container height / width  
    50.       $container.filter(':animated').stop();  
    51.       // disable transition, apply revised style  
    52.       $container.addClass('no-transition').css( style );  
    53.       setTimeout(function(){  
    54.         $container.removeClass('no-transition').isotope( options );  
    55.       }, 100 )  
    56.     } else {  
    57.       $container.isotope( options );  
    58.     }  
    59.   }  
    60.   
    61.   
    62.     
    63.   var $optionSets = $('#options .option-set'),  
    64.       $optionLinks = $optionSets.find('a');  
    65.   
    66.   $optionLinks.click(function(){  
    67.     var $this = $(this);  
    68.     // don't proceed if already selected  
    69.     if ( $this.hasClass('selected') ) {  
    70.       return false;  
    71.     }  
    72.     var $optionSet = $this.parents('.option-set');  
    73.     $optionSet.find('.selected').removeClass('selected');  
    74.     $this.addClass('selected');  
    75.   
    76.     // make option object dynamically, i.e. { filter: '.my-filter-class' }  
    77.     var options = {},  
    78.         key = $optionSet.attr('data-option-key'),  
    79.         value = $this.attr('data-option-value');  
    80.     // parse 'false' as false boolean  
    81.     value = value === 'false' ? false : value;  
    82.     options[ key ] = value;  
    83.     if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {  
    84.       // changes in layout modes need extra logic  
    85.       changeLayoutMode( $this, options )  
    86.     } else {  
    87.       // otherwise, apply new options  
    88.       $container.isotope( options );  
    89.     }  
    90.       
    91.     return false;  
    92.   });  
    93. );  

    显示效果:

    选择fitRows后排列效果:

    完整demo代码:https://github.com/DaweiCheng/isotope-tutorial/blob/master/layout.html

    Isotope中同样可以实现点击element,其中元素动态扩展的效果,即,在运行时,动态改变每个element尺寸;参见代码:https://github.com/DaweiCheng/isotope-tutorial/blob/master/relayout.html

    运行显示效果:

    点中Li元素之后显示效果:

    6. 标记#Hash历史记录

    至此,相信读者已经领略到了Isotope显示的动态布局的神奇之处,使用isotope可以实现你意向不到的绚丽的布局和动画效果。但是可否每次记住布局方式,当点击浏览器返回按钮的时候,返回上次观看的布局方式呢?

    答案是可以的,借助jQuery另一个插件JQuery BBQ来实现。

    jQuery BBQ的官方介绍:jQuery BBQ leverages the HTML5 hashchange event to allow simple, yet powerful bookmarkable #hash history..

    首先在HTML页面中加载需要的JavaScript文件

     
      
    - collapse source view plain copy to clipboard print ?
    1. "js/jquery-1.7.1.min.js">  
    2. "js/jquery.isotope.min.js">  
    3. "js/jquery.ba-bbq.min.js">   

    然后我们在option中,将sorting, filtering,layout modes全部添加进来:

    - collapse source view plain copy to clipboard print ?
    1. "options" class="clearfix">  
    2.   
    3.   

      Filters

        
    4.   
    5.   class="option-set clearfix">  
    6.     
    7. "#filter=*" class="selected">show all
    8.   
    9.     
    10. "#filter=.metal">metal
    11.   
    12.     
    13. "#filter=.transition">transition
    14.   
    15.     
    16. "#filter=.post-transition">post-transition
    17.   
    18.     
    19. "#filter=.nonmetal">nonmetal
    20.   
    21.     
    22. "#filter=.inner-transition">inner-transition
    23.   
    24.     
    25. "#filter=.alkali%2C+.alkaline-earth">alkali and alkaline-earth
    26.   
    27.     
    28. "#filter=%3Anot(.transition)">not transition
    29.   
    30.     
    31. "#filter=.metal%3Anot(.transition)">metal but not transition
    32.   
    33.     
    34.   
    35.   

      Sort

        
    36.   
    37.   class="option-set clearfix">  
    38.     
    39. "#sortBy=original-order" class="selected">original-order
    40.   
    41.     
    42. "#sortBy=name">name
    43.   
    44.     
    45. "#sortBy=symbol">symbol
    46.   
    47.     
    48. "#sortBy=number">number
    49.   
    50.     
    51. "#sortBy=weight">weight
    52.   
    53.     
    54. "#sortBy=category">category
    55.   
    56.     
    57. "#sortBy=random">random
    58.   
    59.     
    60.   
    61.   

      Sort direction

        
    62.   
    63.   class="option-set clearfix">  
    64.     
    65. "#sortAscending=true" class="selected">sort ascending
    66.   
    67.     
    68. "#sortAscending=false">sort descending
    69.   
    70.     
    71.   
    72.   

      Layout modes

        
    73.   
    74.   class="option-set clearfix">  
    75.     
    76. "#layoutMode=masonry" class="selected">masonry
    77.   
    78.     
    79. "#layoutMode=fitRows">fitRows
    80.   
    81.     
    82. "#layoutMode=cellsByRow">cellsByRow
    83.   
    84.     
    85. "#layoutMode=straightDown">straightDown
    86.   
    87.     
    88.   
    89.    

    对应的JavaScript代码中,Hash bookmark history部分代码如下,由于篇幅限制,全部JavaScript代码请参见Github中的文件:

     
      
    - collapse source view plain copy to clipboard print ?
    1. var hashChanged = false;  
    2.   
    3.  $(window).bind( 'hashchange', function( event ){  
    4.    // get options object from hash  
    5.    var hashOptions = window.location.hash ? $.deparam.fragment( window.location.hash, true ) : {},  
    6.        // do not animate first call  
    7.        aniEngine = hashChanged ? 'best-available' : 'none',  
    8.        // apply defaults where no option was specified  
    9.        options = $.extend( {}, defaultOptions, hashOptions, { animationEngine: aniEngine } );  
    10.    // apply options from hash  
    11.    $container.isotope( options );  
    12.    // save options  
    13.    isotopeOptions = hashOptions;  
    14.   
    15.    // if option link was not clicked  
    16.    // then we'll need to update selected links  
    17.    if ( !isOptionLinkClicked ) {  
    18.      // iterate over options  
    19.      var hrefObj, hrefValue, $selectedLink;  
    20.      for ( var key in options ) {  
    21.        hrefObj = {};  
    22.        hrefObj[ key ] = options[ key ];  
    23.        // convert object into parameter string  
    24.        // i.e. { filter: '.inner-transition' } -> 'filter=.inner-transition'  
    25.        hrefValue = $.param( hrefObj );  
    26.        // get matching link  
    27.        $selectedLink = $optionSets.find('a[href="#' + hrefValue + '"]');  
    28.        changeSelectedLink( $selectedLink );  
    29.      }  
    30.    }  
    31.   
    32.    isOptionLinkClicked = false;  
    33.    hashChanged = true;  
    34.  })  
    35.    // trigger hashchange to capture any hash data on init  
    36.    .trigger('hashchange');  

    至此就实现了可标记的#hash历史记录,可以记住所有的排版方式,依次进行返回观看前几次的排版样式。

    本篇全部示例代码:https://github.com/DaweiCheng/isotope-tutorial 欢迎贡献更多的示例代码。


    你可能感兴趣的:(HTML5,CSS3)