Masonry--“瀑布流” 布局(图片较多,推荐在WIFI下查看)

时间:2022-11-16 19:24:13

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 });

属性

所有属性都是可选的,但建议每次都设置columnWidthitemSelector

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>

效果如下:

Masonry--“瀑布流” 布局(图片较多,推荐在WIFI下查看)

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; }

效果如下:

Masonry--“瀑布流” 布局(图片较多,推荐在WIFI下查看)

第一列宽度为320px,则Masonry默认列宽度也为320px,若后面出现宽度小于320px的元素,其右侧会出现空白,非常难看 。

 列宽可以设为固定值,也可以使用符合“选择器”语法的字符串,Masonry会自动寻找其值并添加,如:

columnWidth: '.grid-sizer'

而当设置percentagePositon属性为true,并设置columnWidth为百分比后,可以启用响应式模式。

布局属性

gutter

元素水平方向的间隙,如:

gutter: 10

效果图:

Masonry--“瀑布流” 布局(图片较多,推荐在WIFI下查看)

若想设置垂直方向上的间隙,请使用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

效果如图:

Masonry--“瀑布流” 布局(图片较多,推荐在WIFI下查看)

horizontalOrder

规定元素是否始终从左到右排列,若为false,可能出现意外的效果,如:

Masonry--“瀑布流” 布局(图片较多,推荐在WIFI下查看)

上图中,元素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

效果如图:

Masonry--“瀑布流” 布局(图片较多,推荐在WIFI下查看)

fitWidth

规定容器元素自动调整自身宽度为item元素 列数*列宽,从而,使得容器元素能够设置为在其父元素中水平居中显示,如 :

Masonry--“瀑布流” 布局(图片较多,推荐在WIFI下查看)

注意:fitWidth不能与百分比一起使用,不论columnWidth还是item元素的宽度,都必须 使用固定值,否则,容器元素和item元素的宽度会在一端坍缩。

在Masonry v3中的等价属性是isFitwIdth,且isFitWidth在v4中仍然可以使用。

originLeft

规定元素水平方向的排列顺序,默认为true,即从左到右排列;设为false,可以使元素从右向左排列,如图:

Masonry--“瀑布流” 布局(图片较多,推荐在WIFI下查看)

在Masonry v3中的等价属性为isOriginLeft,在v4中仍然可 以使用。

originTop

规定元素垂直方向的排列顺序,默认为true,即从上到下排列;设为false,可以使元素从下向上排列,如图:

Masonry--“瀑布流” 布局(图片较多,推荐在WIFI下查看)

在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时间格式或一个数字(以毫秒计),如图:

 Masonry--“瀑布流” 布局(图片较多,推荐在WIFI下查看)

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组成的数组·  需要执行删除的元素