分享

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

 root_gao 2012-08-07



2012年07月22日 09:00



目录

1. isotope介绍

2. 简单的isotope例子

3. Sorting & Filtering

4. 动态添加元素

5. 神奇的布局机制

6. 标记#Hash历史记录

1. isotope介绍

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

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

GitHub下载,地址:https://github.com/DaweiCheng/isotope-tutorial。这部分示例代码是对http://isotope./demos/basic.html 中demo的精简。

2. 简单的isotope例子

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

  1. <script src="../js/jquery-1.7.1.min.js"></script>  

  2. <script src="../jquery.isotope.min.js"></script>  


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

  1. <div id="container">  

  2.   <div class="item">...</div>  

  3.   <div class="item">...</div>  

  4.   <div class="item">...</div>  

  5.   ...  

  6. </div>  



在JavaScript中,添加如下代码:

  1. $('#container').isotope({  

  2.   // options  

  3.   itemSelector : '.item',  

  4.   layoutMode : 'fitRows'  

  5. });  



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

layoutMode是用来设定排版的方式,有fitRows, cellsbyRow, strigtDown等等,具体可以看isotope中的源代码和本例中的demo。

设定每个item的CSS样式,详见:https://github.com/DaweiCheng/isotope-tutorial/blob/master/css/style.css 。注:如果需要修改默认的CSS样式,请参考里面的注释。

本例完整代码详见:https://github.com/DaweiCheng/isotope-tutorial/blob/master/basic.html

运行效果如下图所示:

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

3. Sorting and Filtering

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

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

  1. <section id="options" class="clearfix">  

  2.     <h3>Sort</h3>  

  3.      <ul id="sort-by" class="option-set clearfix" data-option-key="sortBy">  

  4.       <li><a href="#sortBy=original-order" data-option-value="original-order" class="selected" data>original-order</a></li>  

  5.       <li><a href="#sortBy=name" data-option-value="name">name</a></li>  

  6.       <li><a href="#sortBy=symbol" data-option-value="symbol">symbol</a></li>  

  7.       <li><a href="#sortBy=number" data-option-value="number">number</a></li>  

  8.       <li><a href="#sortBy=weight"  data-option-value="weight">weight</a></li>  

  9.       <li><a href="#sortBy=category" data-option-value="category">category</a></li>  

  10.       <li><a href="#sortBy=random" data-option-value="random">random</a></li>  

  11.     </ul>  

  12.     <h3>Sort direction</h3>  

  13.     <ul id="sort-direction" class="option-set clearfix" data-option-key="sortAscending">  

  14.       <li><a href="#sortAscending=true" data-option-value="true" class="selected">sort ascending</a></li>  

  15.       <li><a href="#sortAscending=false" data-option-value="false">sort descending</a></li>  

  16.     </ul>  

  17.   </section> <!-- #options -->  



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

Element代码:

  1. <div class="element transition metal   " data-symbol="Hg" data-category="transition">  

  2.   <p class="number">80</p>  

  3.   <h3 class="symbol">Hg</h3>  

  4.   <h2 class="name">Mercury</h2>  

  5.   <p class="weight">200.59</p>  

  6. </div>  



在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.   var $optionSets = $('#options .option-set'),  

  24.       $optionLinks = $optionSets.find('a');  

  25.   $optionLinks.click(function(){  

  26.     var $this = $(this);  

  27.     // don't proceed if already selected  

  28.     if ( $this.hasClass('selected') ) {  

  29.       return false;  

  30.     }  

  31.     var $optionSet = $this.parents('.option-set');  

  32.     $optionSet.find('.selected').removeClass('selected');  

  33.     $this.addClass('selected');  

  34.     // make option object dynamically, i.e. { filter: '.my-filter-class' }  

  35.     var options = {},  

  36.         key = $optionSet.attr('data-option-key'),  

  37.         value = $this.attr('data-option-value');  

  38.     // parse 'false' as false boolean  

  39.     value = value === 'false' ? false : value;  

  40.     options[ key ] = value;  

  41.     if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {  

  42.       // changes in layout modes need extra logic  

  43.       changeLayoutMode( $this, options )  

  44.     } else {  

  45.       // otherwise, apply new options  

  46.       $container.isotope( options );  

  47.     }  

  48.     return false;  

  49.   });  

  50. });  



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

  1. <div class="element transition metal   " data-symbol="Hg" data-category="transition">  

  2.       <p class="number">80</p>  

  3.       <h3 class="symbol">Hg</h3>  

  4.       <h2 class="name">Mercury</h2>  

  5.       <p class="weight">200.59</p>  

  6.     </div>  



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

  1. <section id="options" class="clearfix">  

  2.      <h3>Filters</h3>  

  3.      <ul id="filters" class="option-set clearfix" data-option-key="filter">  

  4.        <li><a href="#filter" data-option-value="*" class="selected">show all</a></li>  

  5.        <li><a href="#filter" data-option-value=".metal">metal</a></li>  

  6.        <li><a href="#filter" data-option-value=".transition">transition</a></li>  

  7.        <li><a href="#filter" data-option-value=".post-transition">post-transition</a></li>  

  8.        <li><a href="#filter" data-option-value=".nonmetal">nonmetal</a></li>  

  9.        <li><a href="#filter" data-option-value=".inner-transition">inner-transition</a></li>  

  10.        <li><a href="#filter" data-option-value=".alkali, .alkaline-earth">alkali and alkaline-earth</a></li>  

  11.        <li><a href="#filter" data-option-value=":not(.transition)">not transition</a></li>  

  12.        <li><a href="#filter" data-option-value=".metal:not(.transition)">metal but not transition</a></li>  

  13.      </ul>  

  14.  </section> <!-- #options -->  



对应的JavaScript function实现如下:

  1. $(function(){  

  2.       var $container = $('#container');  

  3.       $container.isotope({  

  4.         itemSelector : '.element'  

  5.       });  

  6.       var $optionSets = $('#options .option-set'),  

  7.           $optionLinks = $optionSets.find('a');  

  8.       $optionLinks.click(function(){  

  9.         var $this = $(this);  

  10.         // don't proceed if already selected  

  11.         if ( $this.hasClass('selected') ) {  

  12.           return false;  

  13.         }  

  14.         var $optionSet = $this.parents('.option-set');  

  15.         $optionSet.find('.selected').removeClass('selected');  

  16.         $this.addClass('selected');  

  17.         // make option object dynamically, i.e. { filter: '.my-filter-class' }  

  18.         var options = {},  

  19.             key = $optionSet.attr('data-option-key'),  

  20.             value = $this.attr('data-option-value');  

  21.         // parse 'false' as false boolean  

  22.         value = value === 'false' ? false : value;  

  23.         options[ key ] = value;  

  24.         if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {  

  25.           // changes in layout modes need extra logic  

  26.           changeLayoutMode( $this, options )  

  27.         } else {  

  28.           // otherwise, apply new options  

  29.           $container.isotope( options );  

  30.         }  

  31.         return false;  

  32.       });  

  33.     });  



Filter demo演示,全部显示:

筛选所有metal的元素:

4. 动态添加元素

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

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

  1. <section id="options">  

  2.    <ul class="clearfix">  

  3.      <li id="insert"><a href="#insert">Insert new elements</a></li>  

  4.      <li id="append"><a href='#append'>Append new elements</a></li>  

  5.      <li id="prepend"><a href='#prepend'>Prepend</a></li>  

  6.    </ul>  

  7.  </section>  


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

   - collapse sourceview plaincopy to clipboardprint?$(function(){        var $container = $('#container');          $('#insert a').click(function(){      var $newEls = $( fakeElement.getGroup() );      $container.isotope( 'insert', $newEls );        return false;    });      $('#append a').click(function(){      var $newEls = $( fakeElement.getGroup() );      $container.append( $newEls ).isotope( 'appended', $newEls );        return false;    });        $('#prepend a').click(function(){      var $newEls = $( fakeElement.getGroup() );      $container        .prepend( $newEls ).isotope('reloadItems').isotope({ sortBy: 'original-order' })        // set sort back to symbol for inserting        .isotope('option', { sortBy: 'symbol' });        return false;    });      $container.isotope({      itemSelector : '.element',      filter: '*',      getSortData : {        symbol : function( $elem ) {          return $elem.attr('data-symbol');        }      },      sortBy : 'symbol'    });    });
   

完整示例代码https://github.com/DaweiCheng/isotope-tutorial/blob/master/addingItems.html

5. 不同的布局机制

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

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

- collapse sourceview plaincopy to clipboardprint?<section id="options" class="clearfix">        <h3>Layout modes</h3>      <ul id="layouts" class="option-set clearfix" data-option-key="layoutMode">      <li><a href="#masonry" data-option-value="masonry" class="selected">masonry</a></li>      <li><a href="#fitRows" data-option-value="fitRows">fitRows</a></li>      <li><a href="#cellsByRow" data-option-value="cellsByRow">cellsByRow</a></li>      <li><a href="#straightDown" data-option-value="straightDown">straightDown</a></li>      <li><a href="#masonryHorizontal" data-option-value="masonryHorizontal" class="horizontal">masonryHorizontal</a></li>      <li><a href="#fitColumns" data-option-value="fitColumns" class="horizontal">fitColumns</a></li>      <li><a href="#cellsByColumn" data-option-value="cellsByColumn" class="horizontal">cellsByColumn</a></li>      <li><a href="#straightAcross" data-option-value="straightAcross" class="horizontal">straightAcross</a></li>    </ul>  </section> <!-- #options -->

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

  - collapse sourceview plaincopy to clipboardprint?$(function(){        var $container = $('#container');            // add randomish size classes    $container.find('.element').each(function(){      var $this = $(this),          number = parseInt( $this.find('.number').text(), 10 );      if ( number % 7 % 2 === 1 ) {        $this.addClass('width2');      }      if ( number % 3 === 0 ) {        $this.addClass('height2');      }    });        $container.isotope({      itemSelector : '.element',      masonry : {        columnWidth : 120      },      masonryHorizontal : {        rowHeight: 120      },      cellsByRow : {        columnWidth : 240,        rowHeight : 240      },      cellsByColumn : {        columnWidth : 240,        rowHeight : 240      }    });            // change layout    var isHorizontal = false;    function changeLayoutMode( $link, options ) {      var wasHorizontal = isHorizontal;      isHorizontal = $link.hasClass('horizontal');        if ( wasHorizontal !== isHorizontal ) {        // orientation change        // need to do some clean up for transitions and sizes        var style = isHorizontal ?           { height: '80%', width: $container.width() } :           { width: 'auto' };        // stop any animation on container height / width        $container.filter(':animated').stop();        // disable transition, apply revised style        $container.addClass('no-transition').css( style );        setTimeout(function(){          $container.removeClass('no-transition').isotope( options );        }, 100 )      } else {        $container.isotope( options );      }    }            var $optionSets = $('#options .option-set'),        $optionLinks = $optionSets.find('a');      $optionLinks.click(function(){      var $this = $(this);      // don't proceed if already selected      if ( $this.hasClass('selected') ) {        return false;      }      var $optionSet = $this.parents('.option-set');      $optionSet.find('.selected').removeClass('selected');      $this.addClass('selected');        // make option object dynamically, i.e. { filter: '.my-filter-class' }      var options = {},          key = $optionSet.attr('data-option-key'),          value = $this.attr('data-option-value');      // parse 'false' as false boolean      value = value === 'false' ? false : value;      options[ key ] = value;      if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {        // changes in layout modes need extra logic        changeLayoutMode( $this, options )      } else {        // otherwise, apply new options        $container.isotope( options );      }            return false;    });  );

显示效果:

选择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文件

  1. <script src="js/jquery-1.7.1.min.js"></script>  

  2. <script src="js/jquery.isotope.min.js"></script>  

  3. <script src="js/jquery.ba-bbq.min.js"></script>   




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

- collapse sourceview plaincopy to clipboardprint?<section id="options" class="clearfix">      <h3>Filters</h3>      <ul class="option-set clearfix">      <li><a href="#filter=*" class="selected">show all</a></li>      <li><a href="#filter=.metal">metal</a></li>      <li><a href="#filter=.transition">transition</a></li>      <li><a href="#filter=.post-transition">post-transition</a></li>      <li><a href="#filter=.nonmetal">nonmetal</a></li>      <li><a href="#filter=.inner-transition">inner-transition</a></li>      <li><a href="#filter=.alkali%2C+.alkaline-earth">alkali and alkaline-earth</a></li>      <li><a href="#filter=%3Anot(.transition)">not transition</a></li>      <li><a href="#filter=.metal%3Anot(.transition)">metal but not transition</a></li>    </ul>      <h3>Sort</h3>      <ul class="option-set clearfix">      <li><a href="#sortBy=original-order" class="selected">original-order</a></li>      <li><a href="#sortBy=name">name</a></li>      <li><a href="#sortBy=symbol">symbol</a></li>      <li><a href="#sortBy=number">number</a></li>      <li><a href="#sortBy=weight">weight</a></li>      <li><a href="#sortBy=category">category</a></li>      <li><a href="#sortBy=random">random</a></li>    </ul>      <h3>Sort direction</h3>      <ul class="option-set clearfix">      <li><a href="#sortAscending=true" class="selected">sort ascending</a></li>      <li><a href="#sortAscending=false">sort descending</a></li>    </ul>      <h3>Layout modes</h3>      <ul class="option-set clearfix">      <li><a href="#layoutMode=masonry" class="selected">masonry</a></li>      <li><a href="#layoutMode=fitRows">fitRows</a></li>      <li><a href="#layoutMode=cellsByRow">cellsByRow</a></li>      <li><a href="#layoutMode=straightDown">straightDown</a></li>    </ul>    </section> <!-- #options -->

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


  1. var hashChanged = false;  

  2.  $(window).bind( 'hashchange', function( event ){  

  3.    // get options object from hash  

  4.    var hashOptions = window.location.hash ? $.deparam.fragment( window.location.hash, true ) : {},  

  5.        // do not animate first call  

  6.        aniEngine = hashChanged ? 'best-available' : 'none',  

  7.        // apply defaults where no option was specified  

  8.        options = $.extend( {}, defaultOptions, hashOptions, { animationEngine: aniEngine } );  

  9.    // apply options from hash  

  10.    $container.isotope( options );  

  11.    // save options  

  12.    isotopeOptions = hashOptions;  

  13.    // if option link was not clicked  

  14.    // then we'll need to update selected links  

  15.    if ( !isOptionLinkClicked ) {  

  16.      // iterate over options  

  17.      var hrefObj, hrefValue, $selectedLink;  

  18.      for ( var key in options ) {  

  19.        hrefObj = {};  

  20.        hrefObj[ key ] = options[ key ];  

  21.        // convert object into parameter string  

  22.        // i.e. { filter: '.inner-transition' } -> 'filter=.inner-transition'  

  23.        hrefValue = $.param( hrefObj );  

  24.        // get matching link  

  25.        $selectedLink = $optionSets.find('a[href="#' + hrefValue + '"]');  

  26.        changeSelectedLink( $selectedLink );  

  27.      }  

  28.    }  

  29.    isOptionLinkClicked = false;  

  30.    hashChanged = true;  

  31.  })  

  32.    // trigger hashchange to capture any hash data on init  

  33.    .trigger('hashchange');  

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

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

参考文献:http://isotope./

本篇完。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约