Masonry.js是一個以“瀑布流”布局呈現網頁元素的JS庫,它可以使多個不規則寬高的元素以恰當的順序排列 ,增加美觀度。
基本的使用方法如下(以下內容翻譯自masonry官網: https://masonry.desandro.com/):
HTML:
1.導入masonry.js庫
2.以兩層結構包裹將要使用這種布局的元素,結構如下:
1 <div class="grid"> 2 <div class="grid-item">...</div> 3 <div class="grid-item grid-item--width2">...</div> 4 <div class="grid-item">...</div> 5 ... 6 </div>
在.grid-item里面分別放置顯示的內容元素。
CSS:
item元素的尺寸設置全部在CSS內進行,如:
1 .grid-item { width: 200px; } 2 .grid-item--width2 { width: 400px; }
初始化:
提供三種初始化的方式,可按任意選擇
1.以Jquery插件的方式
1 $('.grid').masonry({ 2 itemSelector: '.grid-item', 3 columnWidth: 200 4 });
對選中元素應用masonry方法,並設置初始化參數(參數為對 象格式)。
2.以原生JS方式初始化:
1 var elem = document.querySelector('.grid'); 2 var msnry = new Masonry( elem, { 3 //屬性設置 4 itemSelector: '.grid-item', 5 columnWidth: 200 6 }); 7 8 var msnry = new Masonry( '.grid', { 9 //屬性設置 10 });
第一個參數為外層容器元素(可以是一個原生DOM對象;或者是能唯一確定該元素的,以“’選擇器”語 法表示的字符串),第二個參數是初始化配置對象。
3.直接在HTML中初始化:
<div class="grid" data-masonry='{ "itemSelector": ".grid-item", "columnWidth": 200 }'>
在自定義屬性data-masonry里直接初始化配置對象。選擇這種方式 的話,就無需另寫JS了。
注意:配置對象必須是有效的JSON格式對象,鍵名必須使用雙引號包圍,而因此 data-masonry的值需要使用單引號。
另外,在Masonry v3中初始化是對外層容器元素添加js-masonry類 ,並在data-masonry-options中進行的初始化,Masonry v4能夠向下兼 容這種寫法。
布局
所有尺寸與樣式設置都由CSS完成,如:
1 .grid-item { 2 float: left; 3 width: 80px; 4 height: 60px; 5 border: 2px solid hsla(0, 0%, 0%, 0.5); 6 } 7 8 .grid-item--width2 { width: 160px; } 9 .grid-item--height2 { height: 140px; }
響應式布局
item的尺寸可以設置為百分比來滿足響應式設計的需求,如:
1 <div class="grid"> 2 <!-- width of .grid-sizer used for columnWidth --> 3 <div class="grid-sizer"></div> 4 <div class="grid-item"></div> 5 <div class="grid-item grid-item--width2"></div> 6 ... 7 </div>
1 /* 元素寬度為布局空間寬度的20% */ 2 .grid-sizer, 3 .grid-item { width: 20%; } 4 /* 40% */ 5 .grid-item--width2 { width: 40%; }
1 $('.grid').masonry({ 2 // 將itemSelector設為.grid-item,這樣.grid-sizer就不會被作為item的寬度使用 3 itemSelector: '.grid-item', 4 // 直接以類來設置屬性 5 columnWidth: '.grid-sizer', 6 percentPosition: true 7 })
imagesLoaded
未加載完全的圖片可能會脫離Masonry的布局,並導致item元素發生重疊,而使用imagesLoaded可以解決這個問題。 imagesLoaded是一款獨立的JS腳本,你可以在這里看到更多與imagesloaded相關的信息。
初始化Masonry,然后在每張圖片加載完成后觸發layout,如:
1 // 初始化 Masonry 2 var $grid = $('.grid').masonry({ 3 // 屬性設置... 4 }); 5 // 每張圖片加載完成后觸發layout 6 $grid.imagesLoaded().progress( function() { 7 $grid.masonry('layout'); 8 });
或者,你可以在所有圖片加載完成后初始化Masonry,如:
1 var $grid = $('.grid').imagesLoaded( function() { 2 // 在所有圖片加載完成后初始化Masonry 3 $grid.masonry({ 4 // 屬性設置... 5 }); 6 });
屬性
所有屬性都是可選的,但建議每次都設置columnWidth和itemSelector。
推薦屬性
itemSelector
確定哪些元素作為item元素,對其啟用“瀑布流”布局。itemSelector可以有效排除在容器內,但不應用 “瀑布流”的元素,如:
itemSelector: '.grid-item'
1 <div class="grid"> 2 <!-- do not use banner in Masonry layout --> 3 <div class="static-banner">Static banner</div> 4 <div class="grid-item"></div> 5 <div class="grid-item"></div> 6 ... 7 </div>
效果如下:
columnWidth
容器內每一列的寬度。建議每次都設置該屬性,當未設置時,Masonry會自動以第一個元素的寬度為列寬,可能會造成意外 的效果,如:
1 <div class="grid"> 2 <div class="static-banner">Static banner</div> 3 <div class="grid-item grid-item--width2"></div> 4 <div class="grid-item"></div> 5 ... 6 </div>
1 .grid-item { width: 160px; } 2 .grid-item--width2 { width: 320px; }
效果如下:
第一列寬度為320px,則Masonry默認列寬度也為320px,若后面出現寬度小於320px的元素,其右側會出現空白,非常難看 。
列寬可以設為固定值,也可以使用符合“選擇器”語法的字符串,Masonry會自動尋找其值並添加,如:
columnWidth: '.grid-sizer'
而當設置percentagePositon屬性為true,並設置columnWidth為百分比后,可以啟用響應式模式。
布局屬性
gutter
元素水平方向的間隙,如:
gutter: 10
效果圖:
若想設置垂直方向上的間隙,請使用CSS margin:
1 .grid-item { 2 margin-bottom: 10px; 3 }
同樣的,gutter也可以設置為百分比,以滿足響應式設計,如:
1 <div class="grid"> 2 <div class="grid-sizer"></div> 3 <div class="gutter-sizer"></div> 4 <div class="grid-item"></div> 5 <div class="grid-item grid-item--width2"></div> 6 ... 7 </div>
1 .grid-sizer, 2 .grid-item { width: 22%; } 3 4 .gutter-sizer { width: 4%; } 5 6 .grid-item--width2 { width: 48%; }
1 columnWidth: '.grid-sizer', 2 gutter: '.gutter-sizer', 3 itemSelector: '.grid-item', 4 percentPosition: true
效果如圖:
horizontalOrder
規定元素是否始終從左到右排列,若為false,可能出現意外的效果,如:
上圖中,元素7和8優先填滿垂直方向控件更大(即該列已有元素的總高度最下。當然,總高度相同,還是按規定的水平順 序排列),而不是優先出現在元素9的位置。
percentPosition
規定將元素定位設成百分比。設為true后,元素不必再調整自身寬度來適應容器的尺寸變化。
stamp
規定哪些元素在布局中是固定的,只能在初始化Masonry實例時可以使用stamp來固定元素。其他元素會一次排列在stamp元 素的下(后)面,如:
1 <div class="grid"> 2 <div class="stamp stamp1"></div> 3 <div class="stamp stamp2"></div> 4 <div class="grid-item"></div> 5 <div class="grid-item"></div> 6 .... 7 </div>
1 .stamp { 2 position: absolute; 3 background: orange; 4 border: 4px dotted black; 5 } 6 .stamp1 { 7 left: 30%; 8 top: 10px; 9 width: 20%; 10 height: 100px; 11 } 12 .stamp2 { 13 right: 10%; 14 top: 20px; 15 width: 70%; 16 height: 30px; 17 }
itemSelector: '.grid-item',
stamp: '.stamp
效果如圖:
fitWidth
規定容器元素自動調整自身寬度為item元素 列數*列寬,從而,使得容器元素能夠設置為在其父元素中水平居中顯示,如 :
注意:fitWidth不能與百分比一起使用,不論columnWidth還是item元素的寬度,都必須 使用固定值,否則,容器元素和item元素的寬度會在一端坍縮。
在Masonry v3中的等價屬性是isFitwIdth,且isFitWidth在v4中仍然可以使用。
originLeft
規定元素水平方向的排列順序,默認為true,即從左到右排列;設為false,可以使元素從右向左排列,如圖:
在Masonry v3中的等價屬性為isOriginLeft,在v4中仍然可 以使用。
originTop
規定元素垂直方向的排列順序,默認為true,即從上到下排列;設為false,可以使元素從下向上排列,如圖:
在Masonry v3中的等價屬性為isOriginTop ,在v4中仍然可以使用。
設定參數
containerStyle
將containerStyle設為null,可以使設置在容器元素上的樣式全部失效。
transitionDuration
延長item元素從原來的位置到達新位置的過渡時間,默認為0.4秒,使用css時間格式設置,如:
1 // 快速過渡 2 transitionDuration: '0.2s' 3 4 // 慢速過渡 5 transitionDuration: '0.8s' 6 7 // 無過渡效果,立即移動到新位置 8 transitionDuration: 0
stagger
規定元素位置改變時,每次只移動一個元素。可以使用CSS時間格式或一個數字(以毫秒計),如圖:
resize
當窗口尺寸變化時,調整元素的尺寸和位置,默認為true。
在v3中的等價屬性為isResizeBound,在v4中仍然可以使用。>
initLayout
使布局初始化,默認為true,設為false可以暫停布局的初始化,從而方便在初始化前向Masonry添加事件或方法, 如:
1 var $grid = $('.grid').masonry({ 2 // 禁止布局初始化 3 initLayout: false, 4 //... 5 }); 6 // 綁定事件處理器 7 $grid.masonry( 'on', 'layoutComplete', function() { 8 console.log('layout is complete'); 9 }); 10 // 觸發布局初始化 11 $grid.masonry();
在v3中的等價屬性為isInitLayout ,在v4中仍然可以使用。
方法
使用jQuery時,方法遵循jQuery UI模式.masonry('methodName' /* arguments */ ),如:
1 $grid.masonry() 2 .append( elem ) 3 .masonry( 'appended', elem ) 4 // 布局 5 .masonry();
注意: jQuery的鏈式語法將在帶有返回值的方法出中斷(如:getItemElements, getItem,on,off)。
在使用原生JS時,方法的使用類似 masonry.methodName( /* arguments */ ),與jQuery不同,此時不能使用鏈式語法,如:
1 var msnry = new Masonry( '.grid', {...}); 2 gridElement.appendChild( elem ); 3 msnry.appended( elem ); 4 msnry.layout();
布局相關
layout / .masonry()
對元素按規則進行排列,layout在元素尺寸發生變化,且所有元素、需要重新排列是非常有用。
layoutItems
對指定元素執行排列
1 // jQuery 2 $grid.masonry( 'layoutItems', items, isStill ); 3 // 原生JS 4 msnry.layoutItems( items, isStill );
- items Masonry.Items組成的數組
- isStill Boolean 禁止過渡效 果
stamp
固定指定元素,其他item元素圍繞stamp元素排列
1 // jQuery 2 $grid.masonry( 'stamp', elements ); 3 // 原生JS 4 msnry.stamp( elements );
- elements 原 生元素,jQuery對象,節點列表或者原生元素數組
unstamp
取消元素的固定效果,其他元素將不再圍繞stamp元素排列
添加和移除item元素
appended
添加新元素到容器末尾,並對所有受影響元素進行重新排列
1 // jQuery 2 $grid.masonry( 'appended', elements ); 3 // 原生JS 4 msnry.appended( elements );
- elements 原 生元素,jQuery對象,節點列表或者原生元素數組
栗子:
1 $('.append-button').on( 'click', function() { 2 // 創建新item元素 3 var $items = $('<div class="grid-item">...</div>'); 4 // 將新元素添加到容器元素 5 $grid.append( $items ) 6 // 對新元素和受影響的元素進行重新排列 7 .masonry( 'appended', $items ); 8 });
在jQuery中可以直接用HTML字符串創建元素對象,但原生JS並不支持。當使用jQuery的AJAX方法(如:$get(),$ajax()等 )時,記得將內容包裝成jQuery對象后。再執行添加操作,如:
1 // 這並不能起作用 2 $.get( 'page2', function( content ) { 3 // HTML字符串雖然能夠被添加,但item元素無法添加到Masonry 4 $grid.append( content ).masonry( 'appended', content ); 5 }); 6 7 // 這是正確的用法 8 $.get( 'page2', function( content ) { 9 // 將內容包裹在jQuery對象中 10 var $content = $( content ); 11 // 添加jQuery對象到Masonry實例 12 $grid.append( $content ).masonry( 'appended', $content ); 13 });
prepended
添加新元素到容器元素的開頭,並對所有受影響元素執行重排
1 // jQuery 2 $grid.masonry( 'prepended', elements ); 3 // 原生JS 4 msnry.prepended( elements );
- elements 原 生元素,jQuery對象,節點列表或者原生元素數組
栗子:
1 $('.prepend-button').on( 'click', function() { 2 // 創建新的item元素 3 var $items = $('<div class="grid-item">...</div>'); 4 // 添加新元素到容器元素開頭 5 $grid.prepend( $items ) 6 // 添加新元素到Masonry實例並對所有受影響元素執行重排 7 .masonry( 'prepended', $items ); 8 });
addItems
添加新元素到Masonry實例,但不執行重排
1 // jQuery 2 $grid.masonry( 'addItems', elements ); 3 // 原生JS 4 msnry.addItems( elements );
- elements 原生元素,jQuery對象,節點列表或者原生元素數組
remove
從Masonry和DOM中移除指定元素
1 // jQuery 2 $grid.masonry( 'remove', elements ); 3 // 原生JS 4 msnry.remove( elements );
- elements 原生元素,jQuery對象,節點列表或者原生元素數組
一個栗子:
1 $grid.on( 'click', '.grid-item', function() { 2 // 移除被點擊的item 3 $grid.masonry( 'remove', this ) 4 // 對剩余元素執行重排 5 .masonry('layout'); 6 });
事件
on
添加一個Masonry事件監聽器
1 // jQuery 2 var msnry = $grid.masonry( 'on', eventName, listener ); 3 // 原生JS 4 msnry.on( eventName, listener );
- eventName String · Masonry事件名
- listener 監聽器方法
once
添加一個只執行一次的事件監聽器
1 // jQuery 2 var msnry = $grid.masonry( 'once', eventName, listener ); 3 // 原生JS 4 msnry.once( eventName, listener );
- eventName String · Masonry事件名
- listener 監聽器方法
Utilities
reloadItems
Recollects all item elements.(應該是元素內容變化后,重新收集並整理元素的意思)
對於像Angular和React之類的框架,將改變應用到DOM和Masonry,使用reloadeItems可能更有用。
1 // jQuery 2 $grid.masonry('reloadItems'); 3 // 原生JS 4 msnry.reloadItems();
destroy
完全移除Masonry方法,執行后元素會恢復未應用“瀑布流”布局的狀態
1 // jQuery 2 $grid.masonry('destroy'); 3 // 原生JS 4 msnry.destroy();
一個栗子:
1 var masonryOptions = { 2 itemSelector: '.grid-item', 3 columnWidth: 80 4 }; 5 // 初始化Masonry 6 var $grid = $('.grid').masonry( masonryOptions ); 7 var isActive = true; 8 9 $('.toggle-button').on( 'click', function() { 10 if ( isActive ) { 11 $grid.masonry('destroy'); // destroy 12 } else { 13 $grid.masonry( masonryOptions ); // 重新初始化 14 } 15 // 設置標記 16 isActive = !isActive; 17 });
getItemElements
返回一個item元素組成的數組
1 // jQuery 2 var elems = $grid.masonry('getItemElements'); 3 // 原生JS 4 var elems = msnry.getItemElements();
jQuery.fn.data('masonry')
由一個jQuery對象得到一個Masonry實例。使用Masonry實例可以很方便地獲取到Masonry屬性
1 var msnry = $('.grid').data('masonry'); 2 // 獲取Masonry屬性 3 console.log( msnry.items.length + ' filtered items' );
Masonry.data
通過原生對象獲取其Masonry實例。對於在HTML中完成Masonry實例初始化的情況,通過Masonry.data()可以方便地獲取到 該實例。
var msnry = Masonry.data( element );
- element 原生元素對象或選擇器字符串(原生格式)
獲取的例子:
1 // jQuery 2 // pass in the element, $element[0], not the jQuery object 3 var msnry = Masonry.data( $('.grid')[0] ); 4 5 // 原生JS 6 // 使用element 7 var grid = document.querySelector('.grid'); 8 var msnry = Masonry.data( grid ); 9 // 使用選擇器字符串 10 var msnry = Masonry.data('.grid');
事件
事件綁定
jQuery 事件綁定
用jQuery進行事件綁定,使用.on(),.off()和.one()方法
1 // jQuery 2 var $grid = $('.grid').masonry({...}); 3 4 function onLayout() { 5 console.log('layout done'); 6 } 7 // 綁定事件監聽器 8 $grid.on( 'layoutComplete', onLayout ); 9 // 解綁事件監聽器 10 $grid.off( 'layoutComplete', onLayout ); 11 // 綁定只執行一次的事件監聽器 12 $grid.one( 'layoutComplete', function() { 13 console.log('layout done, just this one time'); 14 });
jQuery用於充當事件監聽器的回調函數可以接受兩個參數,第一個是event,第二個是items,而原生JS則沒有第一個參數 ,如:
1 // jQuery, 有event參數 2 $grid.on( 'layoutComplete', function( event, items ) { 3 console.log( items.length ); 4 }); 5 6 // 原生JS, 無event參數 7 msnry.on( 'layoutComplete', function( items ) { 8 console.log( items.length ); 9 });
原生JS事件綁定
用原生JS進行事件綁定,使用.on(),.off()和.once()方法
1 // 原生JS 2 var msnry = new Masonry( '.grid', {...}); 3 4 function onLayout() { 5 console.log('layout done'); 6 } 7 // 綁定事件監聽器 8 msnry.on( 'layoutComplete', onLayout ); 9 // 解綁事件監聽器 10 msnry.off( 'layoutComplete', onLayout ); 11 // 綁定只執行一次的事件監聽器 12 msnry.once( 'layoutComplete', function() { 13 console.log('layout done, just this one time'); 14 });
Masonry events
layoutComplete
在所有元素重新排列,且過渡動畫全部完成后觸發
1 // jQuery 2 $grid.on( 'layoutComplete', function( event, laidOutItems ) {...} ); 3 // 原生JS 4 msnry.on( 'layoutComplete', function( laidOutItems ) {...} );
- laidOutItems Masonry.Items組成的數組· 需要執行排列的元素
一個栗子:
1 $grid.on( 'layoutComplete', 2 function( event, laidOutItems ) {3 console.log( 'Masonry layout completed on ' + 4 laidOutItems.length + ' items' ); 5 } 6 );
removeComplete
當元素被移除后觸發
1 // jQuery 2 $grid.on( 'removeComplete', function( event, removedItems ) {...} ); 3 // 原生JS 4 msnry.on( 'removeComplete', function( removedItems ) {...} );
- removedItems Masonry.Items組成的數組· 需要執行刪除的元素