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。
Isotope可以工作在一个包含很多类似item的container中,如下面所示:在div container中,声明了很累类似的div item。.
"container">
-
class="item">...
-
class="item">...
-
class="item">...
- ...
在JavaScript中,添加如下代码:
- $('#container').isotope({
-
- itemSelector : '.item',
- layoutMode : 'fitRows'
- });
itemSelector 用来指定container中用来动态排版的元素。
运行效果如下图所示:
调整窗口大小后,排列效果图。
3. Sorting and Filtering
在isotope中,可以动态地对元素进行排序和筛选。
排序的方式很多样化,可以按照元素的不同属性进行排序。首先在HTML页面中添加相应的option:
我们看到,排序的方式包含了element所有的属性。可以进行升序排列也可以降序排列。
Element代码:
class="element transition metal " data-symbol="Hg" data-category="transition">
-
class
="number">80
-
class
="symbol">Hg
-
class
="name">Mercury
-
class
="weight">200.59
在JavaScript中,对每个sorting的方法进行实现:
- $(function(){
- var $container = $('#container');
- $container.isotope({
- itemSelector : '.element',
- getSortData : {
- symbol : function( $elem ) {
- return $elem.attr('data-symbol');
- },
- category : function( $elem ) {
- return $elem.attr('data-category');
- },
- number : function( $elem ) {
- return parseInt( $elem.find('.number').text(), 10 );
- },
- weight : function( $elem ) {
- return parseFloat( $elem.find('.weight').text().replace( /[\(\)]/g, '') );
- },
- name : function ( $elem ) {
- return $elem.find('.name').text();
- }
- }
- });
-
- var $optionSets = $('#options .option-set'),
- $optionLinks = $optionSets.find('a');
- $optionLinks.click(function(){
- var $this = $(this);
-
- if ( $this.hasClass('selected') ) {
- return false;
- }
- var $optionSet = $this.parents('.option-set');
- $optionSet.find('.selected').removeClass('selected');
- $this.addClass('selected');
-
-
- var options = {},
- key = $optionSet.attr('data-option-key'),
- value = $this.attr('data-option-value');
-
- value = value === 'false' ? false : value;
- options[ key ] = value;
- if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {
-
- changeLayoutMode( $this, options )
- } else {
-
- $container.isotope( options );
- }
-
- return false;
- });
- });
筛选的实现:isotope可以筛选不同属性的元素,需要对每个element属性通过class进行标记,如一个典型的element定义如下:
class="element transition metal " data-symbol="Hg" data-category="transition">
-
class
="number">80
-
class
="symbol">Hg
-
class
="name">Mercury
-
class
="weight">200.59
-
在class中表明该元素是transition 而且是metal和
sorting类似,在HTML中添加筛选的option:
- "options" class="clearfix">
-
-
-
Filters
-
- class="option-set clearfix" data-option-key="filter">
-
- "#filter"
data-option-value="*" class="selected">show all
-
- "#filter"
data-option-value=".metal">metal
-
- "#filter"
data-option-value=".transition">transition
-
- "#filter"
data-option-value=".post-transition">post-transition
-
- "#filter"
data-option-value=".nonmetal">nonmetal
-
- "#filter"
data-option-value=".inner-transition">inner-transition
-
- "#filter"
data-option-value=".alkali, .alkaline-earth">alkali and alkaline-earth
-
- "#filter"
data-option-value=":not(.transition)">not transition
-
- "#filter"
data-option-value=".metal:not(.transition)">metal but not transition
-
-
对应的JavaScript function实现如下:
- $(function(){
-
- var $container = $('#container');
-
- $container.isotope({
- itemSelector : '.element'
- });
-
-
- var $optionSets = $('#options .option-set'),
- $optionLinks = $optionSets.find('a');
-
- $optionLinks.click(function(){
- var $this = $(this);
-
- if ( $this.hasClass('selected') ) {
- return false;
- }
- var $optionSet = $this.parents('.option-set');
- $optionSet.find('.selected').removeClass('selected');
- $this.addClass('selected');
-
-
- var options = {},
- key = $optionSet.attr('data-option-key'),
- value = $this.attr('data-option-value');
-
- value = value === 'false' ? false : value;
- options[ key ] = value;
- if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {
-
- changeLayoutMode( $this, options )
- } else {
-
- $container.isotope( options );
- }
-
- return false;
- });
-
-
- });
Filter demo演示,全部显示:
筛选所有metal的元素:
4. 动态添加元素
在isotope中,可以对container中的元素进行动态的删除和添加。
首先还是在HTML页面中添加相应的操作option:
在对应的JavaScript中,添加对function的实现:
- $(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' })
-
- .isotope('option', { sortBy: 'symbol' });
-
- return false;
- });
-
- $container.isotope({
- itemSelector : '.element',
- filter: '*',
- getSortData : {
- symbol : function( $elem ) {
- return $elem.attr('data-symbol');
- }
- },
- sortBy : 'symbol'
- });
-
- });
5. 不同的布局机制
在本例中,我们来尝试isotope中非常神奇的布局机制。
首先在HTML页面中,添加布局机制的选项:
- "options" class="clearfix">
-
-
Layout modes
-
- class="option-set clearfix" data-option-key="layoutMode">
-
- "#masonry"
data-option-value="masonry" class="selected">masonry
-
- "#fitRows"
data-option-value="fitRows">fitRows
-
- "#cellsByRow"
data-option-value="cellsByRow">cellsByRow
-
- "#straightDown"
data-option-value="straightDown">straightDown
-
- "#masonryHorizontal"
data-option-value="masonryHorizontal" class="horizontal">masonryHorizontal
-
- "#fitColumns"
data-option-value="fitColumns" class="horizontal">fitColumns
-
- "#cellsByColumn"
data-option-value="cellsByColumn" class="horizontal">cellsByColumn
-
- "#straightAcross"
data-option-value="straightAcross" class="horizontal">straightAcross
-
-
在JavaScript代码中实现相应的布局机制:
- $(function(){
-
- var $container = $('#container');
-
-
-
- $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
- }
- });
-
-
-
- var isHorizontal = false;
- function changeLayoutMode( $link, options ) {
- var wasHorizontal = isHorizontal;
- isHorizontal = $link.hasClass('horizontal');
-
- if ( wasHorizontal !== isHorizontal ) {
-
-
- var style = isHorizontal ?
- { height: '80%', width: $container.width() } :
- { width: 'auto' };
-
- $container.filter(':animated').stop();
-
- $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);
-
- if ( $this.hasClass('selected') ) {
- return false;
- }
- var $optionSet = $this.parents('.option-set');
- $optionSet.find('.selected').removeClass('selected');
- $this.addClass('selected');
-
-
- var options = {},
- key = $optionSet.attr('data-option-key'),
- value = $this.attr('data-option-value');
-
- value = value === 'false' ? false : value;
- options[ key ] = value;
- if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {
-
- changeLayoutMode( $this, options )
- } else {
-
- $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文件
- collapse source view plain copy to clipboard print ?
-
-
-
然后我们在option中,将sorting, filtering,layout modes全部添加进来:
对应的JavaScript代码中,Hash bookmark history部分代码如下,由于篇幅限制,全部JavaScript代码请参见Github中的文件:
- collapse source view plain copy to clipboard print ?
- var hashChanged = false;
-
- $(window).bind( 'hashchange', function( event ){
-
- var hashOptions = window.location.hash ? $.deparam.fragment( window.location.hash, true ) : {},
-
- aniEngine = hashChanged ? 'best-available' : 'none',
-
- options = $.extend( {}, defaultOptions, hashOptions, { animationEngine: aniEngine } );
-
- $container.isotope( options );
-
- isotopeOptions = hashOptions;
-
-
-
- if ( !isOptionLinkClicked ) {
-
- var hrefObj, hrefValue, $selectedLink;
- for ( var key in options ) {
- hrefObj = {};
- hrefObj[ key ] = options[ key ];
-
-
- hrefValue = $.param( hrefObj );
-
- $selectedLink = $optionSets.find('a[href="#' + hrefValue + '"]');
- changeSelectedLink( $selectedLink );
- }
- }
-
- isOptionLinkClicked = false;
- hashChanged = true;
- })
-
- .trigger('hashchange');
至此就实现了可标记的#hash历史记录,可以记住所有的排版方式,依次进行返回观看前几次的排版样式。
本篇全部示例代码:https://github.com/DaweiCheng/isotope-tutorial 欢迎贡献更多的示例代码。