英文原版网站链接:http://masonry.desandro.com/。英文原版包含大量例程,请对照阅读。
Masonry是一个JavaScript网格布局库。它的作用是在可用的竖直空间上将页面元素放置于页面最佳位置处,就像泥瓦匠将石头往墙上砌一样。你应该已经在网上很多地方见过它了。
Masonry.pkgd.min.js 压缩过的源码,或者
Masonry.pkgd.js 未经压缩的源码。
直接链接至upmcdn上的Masonry文件。
<script src="https://npmcdn.com/[email protected]/dist/masonry.pkgd.min.js">script>
<script src="https://npmcdn.com/[email protected]/dist/masonry.pkgd.js">script>
通过Bower安装: bower install masonry --save
通过npm安装:npm install masonry-layout
将Masonry的.js
文件include进你的站点。
<script src="/path/to/masonry.pkgd.min.js">script>
Masonry的工作需要一个包含若干子项的容器。
"grid">
"grid-item">...
"grid-item grid-item--width2">...
"grid-item">...
...
所有项的尺寸都由你的CSS决定。
.grid-item { width: 200px; }
.grid-item--width2 { width: 400px; }
你能将Masonry作为一个jQuery插件使用:$('selector').masonry()
。
$('.grid').masonry({
// options
itemSelector: '.grid-item',
columnWidth: 200
});
你可以通过vanilla JS使用Masonry:new Masonry( elem, options )
。Masonry() 构造器接受两个参数:容器参数和一个设置对象。
var elem = document.querySelector('.grid');
var msnry = new Masonry( elem, {
// options
itemSelector: '.grid-item',
columnWidth: 200
});
// element argument can be a selector string
// for an individual element
var msnry = new Masonry( '.grid', {
// options
});
你可以在HTML中初始化Masonry,不需要写一行JavaScript。给容器元素添加data-masonry
属性。通过修改它的值就能更改设置。
<div class="grid" data-masonry='{ "itemSelector": ".grid-item", "columnWidth": 200 }'>
在CodePen中编写这个demo
注意:HTML中的设置值必须是可用的JSON,键必须加引号,比如"itemSelector":
。注意data-masonry
的值是被单引号包'
裹的,而JSON条目用的是双引号"
。
HTML初始化的完成是先于js-masonry
的。Masonry v3和Masonry v4版本中data-masonry-options
的设置同现在的代码是向后兼容的。
<div class="grid js-masonry"
data-masonry-options='{ "itemSelector": ".grid-item", "columnWidth": 200 }'>
项的所有尺寸及样式都由你自己的CSS决定。
<div class="grid">
<div class="grid-item">div>
<div class="grid-item grid-item--width2">div>
<div class="grid-item grid-item--height2">div>
...
div>
.grid-item {
float: left;
width: 80px;
height: 60px;
border: 2px solid hsla(0, 0%, 0%, 0.5);
}
.grid-item--width2 { width: 160px; }
.grid-item--height2 { height: 140px; }
查看并编辑demo
在响应式布局中项的大小可以以百分比的形式来设置。在masonry
布局模式中,设置百分比宽度columWidth
来更改元素的大小。设置percentPosition:true
,项的位置也同样变为了百分比式,从而能够减少窗口大小变动时项位置的调整变动。
<div class="grid">
<div class="grid-sizer">div>
<div class="grid-item">div>
<div class="grid-item grid-item--width2">div>
...
div>
/* fluid 5 columns */
.grid-sizer,
.grid-item { width: 20%; }
/* 2 columns */
.grid-item--width2 { width: 40%; }
$('.grid').masonry({
// set itemSelector so .grid-sizer is not used in layout
itemSelector: '.grid-item',
// use element for option
columnWidth: '.grid-sizer',
percentPosition: true
})
查看并编辑demo
未载入的图片可能脱离Masonry布局并导致项元素重叠。imagesLoaded
解决了这个问题。imagesLoaded
是单独的脚本,你可以在imagesloaded.desandro.com下载。
初始化Masonry,然后再每张图片载入后触发layout
(布局)。
// init Masonry
var $grid = $('.grid').masonry({
// options...
});
// layout Masonry after each image loads
$grid.imagesLoaded().progress( function() {
$grid.masonry('layout');
});
查看并编辑demo
或者当所有图片载入后在初始化Masonry。
var $grid = $('.grid').imagesLoaded( function() {
// init Masonry after all images have loaded
$grid.masonry({
// options...
});
});
查看并编辑demo
所有的选项都是可选的,建议保留columWidth
和itemSelector
。
// jQuery
$('.grid').masonry({
columnWidth: 200,
itemSelector: '.grid-item'
});
// vanilla JS
var msnry = new Masonry( '.grid', {
columnWidth: 200,
itemSelector: '.grid-item'
});
<div class="grid" data-masonry='{ "columnWidth": 200, "itemSelector": ".grid-item" }'>
指定将在布局中作为项的子元素。
我们建议总是保留设置itemSelector
。在排除sizing elements
(尺寸元素)或者其他非布局所需元素的时候它将很有用。
itemSelector: '.grid-item'
<div class="grid">
<div class="static-banner">Static bannerdiv>
<div class="grid-item">div>
<div class="grid-item">div>
...
div>
将项排列在一个水平栅格上。
注意:我们建议设置columWidth
。如果columWidth
未设置,Masonry将使用第一个项的外部宽度。
columnWidth: 80
查看并编辑demo
在响应式布局中使用element sizing
实现百分比宽度。设置columWidth
为一个元素或者选择器的字符串名称来使用该元素的外部宽度作为该行的尺寸。
<div class="grid">
<div class="grid-sizer">div>
<div class="grid-item">div>
<div class="grid-item grid-item--width2">div>
...
div>
/* fluid 5 columns */
.grid-sizer,
.grid-item { width: 20%; }
/* 2 columns wide */
.grid-item--width2 { width: 40%; }
// use outer width of grid-sizer for columnWidth
columnWidth: '.grid-sizer',
itemSelector: '.grid-item',
percentPosition: true
尺寸选项cloumnWidth
和gutter
可设置为某个元素。该元素的尺寸即成为了该选项的设置值。
<div class="grid">
<div class="grid-sizer">div>
<div class="grid-item">div>
<div class="grid-item grid-item--width2">div>
...
div>
/* fluid 5 columns */
.grid-sizer,
.grid-item { width: 20%; }
/* 2 columns wide */
.grid-item--width2 { width: 40%; }
// use outer width of grid-sizer for columnWidth
columnWidth: '.grid-sizer',
// do not use .grid-sizer in layout
itemSelector: '.grid-item',
percentPosition: true
编辑并查看demo
尺寸选项也能设置为元素或者选择器的字符串名称。
// set to a selector string
// first matching element within container element will be used
columnWidth: '.grid-sizer'
// set to an element
columnWidth: $grid.find('.grid-sizer')[0]
元素尺寸选项让你可以用自己的CSS来控制Masonry布局的大小。它特别适用于响应式布局和媒体查询。
/* 3 columns by default */
.grid-sizer { width: 33.333%; }
@media screen and (min-width: 768px) {
/* 5 columns for larger screens */
.grid-sizer { width: 20%; }
}
添加项元素间的横向间隔。
gutter: 10
查看并编辑demo
要改变元素间竖直方向上的间隔,请使用margin
CSS。
gutter: 10
.grid-item {
margin-bottom: 10px;
}
查看并编辑demo
在响应式布局中,设置gutter
为一个元素或者选择器名称的字符串来使用元素的外部尺寸。
<div class="grid">
<div class="grid-sizer">div>
<div class="gutter-sizer">div>
<div class="grid-item">div>
<div class="grid-item grid-item--width2">div>
...
div>
.grid-sizer,
.grid-item { width: 22%; }
.gutter-sizer { width: 4%; }
.grid-item--width2 { width: 48%; }
columnWidth: '.grid-sizer',
gutter: '.gutter-sizer',
itemSelector: '.grid-item',
percentPosition: true
查看并编辑demo
将项的位置设为百分比优于设为像素值。percentPosition:true
与百分比宽度项一起的效果不错,当窗口大小改变时项的相对位置将不会变化。
// set positions with percent values
percentPosition: true,
columnWidth: '.grid-sizer',
itemSelector: '.grid-item'
/* fluid 5 columns */
.grid-sizer,
.grid-item { width: 20%; }
查看并编辑demo
指明布局里哪些元素会像邮票一样被贴在最面上。Masonry将在stamp
元素之下布局各项。
stamp
设置只有在Masonry实例第一次初始化的时候操作才有效。你可以用stamp
方法随后添加额外的邮票元素。
<div class="grid">
<div class="stamp stamp1">div>
<div class="stamp stamp2">div>
<div class="grid-item">div>
<div class="grid-item">div>
....
div>
// specify itemSelector so stamps do get laid out
itemSelector: '.grid-item',
// stamp elements
stamp: '.stamp'
/* position stamp elements with CSS */
.stamp {
position: absolute;
background: orange;
border: 4px dotted black;
}
.stamp1 {
left: 30%;
top: 10px;
width: 20%;
height: 100px;
}
.stamp2 {
right: 10%;
top: 20px;
width: 70%;
height: 30px;
}
查看并编辑demo
基于容器父类的尺寸设置容器的宽度来适应恰当的行数。当设为可用,你能够通过CSS使容器剧中。
fitWidth
在Masonry v3版本中是isFitWIdth
。isFitWidth
在Masonry v4中依旧可用。
注意:fitWidth:true
与element sizing一起的时候百分比宽度不会生效。要么columnWidth
需要被设置为固定尺寸,比如columnWidth:120
;要么项被设置为像素固定值,比如width:120px
。如果不然,容器跟项宽将逐个重叠。
fitWidth: true
/* center container with CSS */
.grid {
margin: 0 auto;
}
查看并编辑demo
控制布局的水平流动。默认项元素从左向右安置,originLeft:true
。设originLeft:false
将变成由右向左的布局。
originLeft
在Masonry v3中曾经是isOriginLeft
。isOriginLeft
在Masonry v4中依旧可用。
originLeft: false
查看并编辑demo
控制布局的垂向流动。默认originTop:true
。设originTop:false
将变为由下到上的布局,就像俄罗斯方块一样。
originTop: false
查看并编辑demo
被应用于容器元素的CSS样式。
// default
// containerStyle: { position: 'relative' }
// disable any styles being set on container
// useful if using absolute position on container
containerStyle: null
当项改变位置或外观时过渡效果的持续时间,按照CSS时间的格式设置,默认:transitionDuration:'0.4s'
// fast transitions
transitionDuration: '0.2s'
// slow transitions
transitionDuration: '0.8s'
// no transitions
transitionDuration: 0
项转换位置时为其提供交错效果,使项能够一个接一个的转换位置。按照CSS时间的格式设置,'0.03s'
,或者用以毫秒为单位的数字,30
。
stagger: 30
当窗口大小改变时调整尺寸和位置。默认启用:resize:true
。
resize
曾经在Masonry v3中为isResizeBound
。isResizeBound
在Masonry v4中依旧可用。
// disable window resize behavior
resize: false
/* grid has fixed width */
.grid {
width: 320px;
}
查看并编辑demo
使布局在初始化时启用。默认启用initLayout:true
。
设initLayout:false
将使初始化时的布局不可用,以便能够在初始布局之前调用方法或添加事件。
initLayou
t曾经在Masonry v3中为isInitLayout
。在Masonry v4中isInitLayout
将依旧可用。
var $grid = $('.grid').masonry({
// disable initial layout
initLayout: false,
//...
});
// bind event
$grid.masonry( 'on', 'layoutComplete', function() {
console.log('layout is complete');
});
// trigger initial layout
$grid.masonry();
查看并编辑demo
方法是由Masonry实例执行的各种动作。
用jQuery的时候,方法的使用遵从jQuery的UI模式.masonry( 'methodName' /* arguments */ )
。
$grid.masonry()
.append( elem )
.masonry( 'appended', elem )
// layout
.masonry();
注意:jQuery链会被那些返回值的方法打断:(比如getItemElements
,getItem
,on
,off
)。
Vanilla JavaScript方法是这样的masonry.methodName(/*arguments*/)
。不同于jQuery方法,他们不能链在一起。
// vanilla JS
var msnry = new Masonry( '.grid', {...});
gridElement.appendChild( elem );
msnry.appended( elem );
msnry.layout();
布局出所有的项元素。当某一项改变了尺寸,所有项需要重新布局时layout
很有用处。
// jQuery
$grid.masonry()
// vanilla JS
msnry.layout()
var $grid = $('.grid').masonry({
columnWidth: 80
});
// change size of item by toggling gigante class
$grid.on( 'click', '.grid-item', function() {
$(this).toggleClass('gigante');
// trigger layout after item size changes
$grid.masonry('layout');
});
查看并编辑jQuery demo或者vanilla JS demo
布局出特定的项。
// jQuery
$grid.masonry( 'layoutItems', items, isStill )
// vanilla JS
msnry.layoutItems( items, isStill )
items
· Masonry.Items数组
isStill
· 布尔值 · 禁止过渡效果
在布局中“粘贴”元素。Masonry将会围绕邮票元素布局。
// jQuery
$grid.masonry( 'stamp', elements )
// vanilla JS
msnry.stamp( elements )
elements
· Element, jQuery 对象, NodeList, 或者元素数组
设置itemSelector使邮票元素不被当作layout items(布局项)使用。
var $grid = $('.grid').masonry({
// specify itemSelector so stamps do get laid out
itemSelector: '.grid-item',
columnWidth: 80
});
var $stamp = $grid.find('.stamp');
var isStamped = false;
$('.stamp-button').on( 'click', function() {
// stamp or unstamp element
if ( isStamped ) {
$grid.masonry( 'unstamp', $stamp );
} else {
$grid.masonry( 'stamp', $stamp );
}
// trigger layout
$grid.masonry('layout');
// set flag
isStamped = !isStamped;
});
查看并编辑jQuery demo 或者 vanilla JS demo
布局中取消元素的邮票效果,使Masonry不再围绕它们布局项元素。见上面的demo。
// jQuery
$grid.masonry( 'unstamp', elements )
// vanilla JS
msnry.unstamp( elements )
elements
· 元素, jQuery对象, NodeList, 或者元素数组
在布局的末尾添加并展示新的项元素。
// jQuery
$grid.masonry( 'appended', elements )
// vanilla JS
msnry.appended( elements )
elements
· 元素, jQuery对象, NodeList, 或者元素数组
$('.append-button').on( 'click', function() {
// create new item elements
var $items = $('...');
// append items to grid
$grid.append( $items )
// add and lay out newly appended items
.masonry( 'appended', $items );
});
查看并编辑jQuery demo或者vanilla JS demo
不像jQuery的.append()
能直接添加一个HTML字符串,Masonry的appende
不能。当通过jQeury ajax方法(比如$.get()
或$.ajax()
)添加内容的时候,应将HTML内容字符串包裹于一个jQuery对象当中,使得appended
能够正常工作。
在布局的开头添加并展示新的项元素。
// jQuery
$grid.masonry( 'prepended', elements )
// vanilla JS
msnry.prepended( elements )
elements
· 元素, jQuery对象, NodeList, 或者元素数组
$('.prepend-button').on( 'click', function() {
// create new item elements
var $items = $('...');
// prepend items to grid
$grid.prepend( $items )
// add and lay out newly prepended items
.masonry( 'prepended', $items );
});
查看并编辑jQuery demo或者vanilla JS demo
给Masonry实例添加项元素。addItems
并不会像appended
或prepended
一样将项元素展示出来。
// jQuery
$grid.masonry( 'addItems', elements )
// vanilla JS
msnry.addItems( elements )
elements
· 元素, jQuery对象, NodeList, 或者元素数组
移除Masonry实例和DOM中的元素。
// jQuery
$grid.masonry( 'remove', elements )
// vanilla JS
msnry.remove( elements )
elements
· 元素, jQuery对象, NodeList, 或者元素数组
$grid.on( 'click', '.grid-item', function() {
// remove clicked element
$grid.masonry( 'remove', this )
// layout remaining item elements
.masonry('layout');
});
查看或编辑 jQuery demo 或者vanilla JS demo
添加Masonry事件监听器。
// jQuery
var msnry = $grid.masonry( 'on', eventName, listener )
// vanilla JS
msnry.on( eventName, listener )
eventName
· Masonry事件的字符串名称
listener
· Function
移除一个事件监听器。
// jQuery
var msnry = $grid.masonry( 'off', eventName, listener )
// vanilla JS
msnry.off( eventName, listener )
eventName
· string · Masonry事件的名称
listener
· Function
添加一个仅会被触发一次的Masonry事件监听器。
// jQuery
var msnry = $grid.masonry( 'once', eventName, listener )
// vanilla JS
msnry.once( eventName, listener )
eventName
· string · Masonry事件的名称
listener
· Function
$grid.masonry( 'once', 'layoutComplete', function() {
console.log('layout is complete, just once');
})
重新收集所有的项元素。
对于像Angular和React一类的框架,在DOM有变更时Masonry中可以用上。
// jQuery
$grid.masonry('reloadItems')
// vanilla JS
msnry.reloadItems()
完全移除Masonry功能。destroy会使元素返回最初的状态。
var masonryOptions = {
itemSelector: '.grid-item',
columnWidth: 80
};
// initialize Masonry
var $grid = $('.grid').masonry( masonryOptions );
var isActive = true;
$('.toggle-button').on( 'click', function() {
if ( isActive ) {
$grid.masonry('destroy'); // destroy
} else {
$grid.masonry( masonryOptions ); // re-initialize
}
// set flag
isActive = !isActive;
});
查看并编辑 jQuery demo 或者 vanilla JS demo
以数组形式范围一组项元素。
// jQuery
var elems = $grid.masonry('getItemElements')
// vanilla JS
var elems = msnry.getItemElements()
elems
· 元素数组
从jQuery对象中获取Masonry实例。Masonry实例在使用Masonry属性时很用有。
var msnry = $('.grid').data('masonry')
// access Masonry properties
console.log( msnry.items.length + ' filtered items' )
通过Masonry实例的元素获取Masonry实例。Masonry.data()在通过JavaScript获取Masonry实例时很有用,当Masonry在HTML中初始化以后。
var msnry = Masonry.data( element )
element
· 元素或者选择器名称的字符串
msnry
· Masonry
<div class="grid" data-masonry='{...}'>...div>
// jQuery
// pass in the element, $element[0], not the jQuery object
var msnry = Masonry.data( $('.grid')[0] )
// vanilla JS
// using an element
var grid = document.querySelector('.grid')
var msnry = Masonry.data( grid )
// using a selector string
var msnry = Masonry.data('.grid')
通过标准的jQuery事件方法.on()
, .off()
,还有 .one()
绑定事件。
// jQuery
var $grid = $('.grid').masonry({...});
function onLayout() {
console.log('layout done');
}
// bind event listener
$grid.on( 'layoutComplete', onLayout );
// un-bind event listener
$grid.off( 'layoutComplete', onLayout );
// bind event listener to be triggered just once. note ONE not ON
$grid.one( 'layoutComplete', function() {
console.log('layout done, just this one time');
});
jQuery事件监听器具有一个event
参数,而 vanilla JS 没有。
// jQuery, has event argument
$grid.on( 'layoutComplete', function( event, items ) {
console.log( items.length );
});
// vanilla JS, no event argument
msnry.on( 'layoutComplete', function( items ) {
console.log( items.length );
});
用vanilla JS 的方法.on()
, .off()
,还有 .once()
绑定事件。
// vanilla JS
var msnry = new Masonry( '.grid', {...});
function onLayout() {
console.log('layout done');
}
// bind event listener
msnry.on( 'layoutComplete', onLayout );
// un-bind event listener
msnry.off( 'layoutComplete', onLayout );
// bind event listener to be triggered just once
msnry.once( 'layoutComplete', function() {
console.log('layout done, just this one time');
});
在布局和所有的位置转换效果完成后触发。
// jQuery
$grid.on( 'layoutComplete', function( event, laidOutItems ) {...} )
// vanilla JS
msnry.on( 'layoutComplete', function( laidOutItems ) {...} )
laidOutItems
· Masonry.Items数组 · 被展示出的项
$grid.on( 'layoutComplete',
function( event, laidOutItems ) {
console.log( 'Masonry layout completed on ' +
laidOutItems.length + ' items' );
}
);
查看并编辑 jQuery demo 或者 vanilla JS demo
在某个项元素被移除后触发。
// jQuery
$grid.on( 'removeComplete', function( event, removedItems ) {...} )
// vanilla JS
msnry.on( 'removeComplete', function( removedItems ) {...} )
removedItems
· Masonry.Items数组 · 被移除的项
$grid.on( 'removeComplete',
function( event, removedItems ) {
notify( 'Removed ' + removedItems.length + ' items' );
}
);
查看并编辑 jQuery demo 或者 vanilla JS demo
后续Extras及FAQ部分内容请查看英文原文
译者: DK
微信: dksyydnr