Masonry--“瀑布流” 布局
Masonry js是一个以瀑布流布局呈现网页元素的JS库,它可以使多个不规则宽高的元素以恰当的顺序排列 ,增加美观度。基本的使用方法如下:HT
Masonry.js是一个以“瀑布流”布局呈现网页元素的JS库,它可以使多个不规则宽高的元素以恰当的顺序排列 ,增加美观度。
基本的使用方法如下:
HTML:
1.导入masonry.js库
2.以两层结构包裹将要使用这种布局的元素,结构如下:
<div class="grid"> <div class="grid-item">...</div> <div class="grid-item grid-item--width2">...</div> <div class="grid-item">...</div> ... </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组成的数组· 需要执行删除的元素