我正在尝试创建一个布局,其左上方有一个印章(2x2),右边有2个块(1x1),后面是另一个印章(2x2),右边是第一个印章下面的2个块(1x1)。 简单来说,这是一个简单的问题示例: http://codepen.io/wpsmith/pen/meXoEW
相关:https://github.com/desandro/masonry/issues/779
具体地: 以下是我想要实现的目标:http://bit.ly/1NrOPbj
以下是网站:http://bit.ly/1LrMDjw 以下是代码:http://codepen.io/wpsmith/pen/NGyeoG?editors=001
这是砌体初始化JS代码:
/*! jquery.masonry.init.js 1.0.38
* http://wpsmith.net
*
* Copyright (c) 2015 @wp_smith
* Available under the MIT license
*/
var WPS = WPS || {};
WPS.masonry = (function ($, window, document) {
"use strict";
var app = {
itemSelector: '.capability-item',
masonryTO: 250,
$previousEntry: null,
resizeTO: 500,
//context: gjm.context
};
/**
* Caching jQuery elements
*/
app.cache = function cache() {
app.$grid = $('.capabilities-container');
app.$entries = $('.entry');
app.$images = app.$grid.find('img.not-loaded');
app.$stamp = app.$grid.find('.stamp');
app.$stamp1 = app.$grid.find('.stamp-1');
app.$stamp2 = app.$grid.find('.stamp-2');
app.$stamp3 = app.$grid.find('.stamp-3');
};
/**
* Create <style> element to be inserted into the header
*/
app.createStyle = function createStyle() {
var w = 0;
// Create the DOM element
app.style = document.createElement('style');
app.style.type = 'text/css';
app.style.id = 'dynamic';
// Get width (for setting height)
console.log('----------------------------WIDTH----------------------------');
//app.width = $(app.$grid.find('.entry:not(.stamp)').get(0)).width();
console.log('width: ' + $(app.$grid.find('.entry:not(.stamp)').get(0)).width());
app.width = Math.floor(app.$grid.find('.entry:not(.stamp)').get(0).getBoundingClientRect().width);
//app.width = Math.floor($(window).width() / 4);
console.log('width floored: ' + app.width);
w = app.width / $(window).width() * 100;
console.log('width percentage: ' + w);
app.addStylesContent('.grid .one-fourth-full,.grid .grid-item{width:' + w + '% !important;}');
app.addStylesContent('.grid .featured,.grid .stamp,.grid .entry--width2,.grid .grid-item--width2{width:' + ( w * 2 ) + '% !important;}');
// Ensure stamps are ready
app.doStamps();
// Add style to DOM
app.appendStyles();
};
/**
* Add custom dynamic styles to style node
* @param {array} elements Array of jQuery elements
*/
app.addStyles = function addStyles(elements) {
var css = '';
$.each(elements, function (i, e) {
css += '.grid ' + i + '.grid-item{top:' + e.top + 'px;}';
});
app.addStylesContent(css);
};
/**
* Add custom dynamic styles to style node
* @param {array} elements Array of jQuery elements
*/
app.addStylesContent = function addStylesContent(content) {
if (app.style.styleSheet) {
app.style.styleSheet.cssText = content;
} else {
app.style.appendChild(document.createTextNode(content));
}
};
/**
* Appends dynamic styles to header
*/
app.appendStyles = function appendStyles() {
//app.$grid.prepend(app.style);
document.getElementsByTagName('head')[0].appendChild(app.style);
};
/**
* Remove Style tag.
*/
app.removeStyles = function removeStyles() {
$('style#dynamic').remove();
};
/**
* Cycles through the various stamp elements to determine the proper top offset
* Need CSS4:nth-math
*
* @param {array} $stamps Array of jQuery elements.
* @param {int} offset Offset from top.
*/
app.doStampStyle = function doStampStyle($stamps, offset) {
var top = offset || 0,
elements = {};
$stamps
.each(function (i, e) {
elements['.post-' + $(e).data('id')] = {
top: top
};
top += app.width;
});
app.addStyles(elements);
};
/**
* Performs the dynamic stamp style modifications & ensures the proper height of featured items.
*/
app.doStamps = function doStamps() {
var height = 0;
app.$stamp
.each(function (i, e) {
var h = app.width * 2;
$(e).find('.item').css('height', h);
$(e)
.removeClass('entry')
.css({
'height': h
//'top': height
});
height += app.width;
});
app.doStampStyle(app.$stamp1);
app.doStampStyle(app.$stamp2, app.width);
app.doStampStyle(app.$stamp3, app.width * 2);
app.appendStyles();
};
/**
* Initializes everything: cache, doStamps, sets up the grid, initializes masonry, lazy load, & adds eventlisteners
*/
app.init = function init() {
// Set cache
app.cache();
// Create dynamic style (as opposed to imposing on DOM elements, allowing Masonry to over-ride).
app.createStyle();
// Setup Grid
app.$grid.addClass('grid');
app.$grid.prepend('<div class="grid-sizer"></div>').prepend('<div class="gutter-sizer"></div>');
// Remove image sizes
app.$grid.find('img').attr('width', '').attr('height', '');
// Let's do the fanciness!
app.doMasonry();
app.lazyload();
// Observe the container
app.watch();
};
/**
* Triger masonry layout or stamp layout, scroll for lazy load
* @param {bool|string} type Whether Masonry should be triggered.
*/
app.trigger = function trigger(type) {
app.$grid.find('img.not-loaded').trigger('scroll');
if (type) {
if ('stamp' === type && false) {
app.$grid.masonry('stamp', app.$stamp);
}
app.$grid.masonry('layout');
}
};
/**
* Initialize LazyLoad
*/
app.lazyload = function lazyLoad() {
app.$images.lazyload({
effect: 'fadeIn',
failure_limit: Math.max(app.$images.length - 1, 0),
threshold: 0,
load: function () {
// Disable trigger on this image
$(this).removeClass("not-loaded");
//app.$grid.masonry('reload');
//app.$grid.masonry();
app.trigger(true);
}
});
//app.$images.trigger('scroll');
//app.$grid.masonry();
//$('.item img.not-loaded').trigger('scroll');
};
/**
* Instantiates Masonry.
*/
app.doMasonry = function doMasonry() {
var opts = {
// options
itemSelector: '.entry',
columnWidth: app.width, //app.$grid.width() / 4,
//columnWidth: '.grid-sizer',
//columnWidth: width, //'.grid-sizer',
gutter: '.gutter-sizer',
percentPosition: true,
isFitWidth: false,
containerStyle: true,
isResizeBound: true,
isInitLayout: false,
stamp: '.stamp',
isAnimated: true,
onLayout: app.trigger
};
app.$grid.masonry(opts);
// bind event
app.$grid.masonry('once', 'layoutComplete', function () {
console.log('layout is complete-once');
$(window).trigger('scroll');
//$(window).trigger('reload');
//app.$grid.masonry();
//app.trigger('stamp');
});
// manually trigger initial layout
app.trigger('stamp');
//app.$grid.masonry();
};
/**
* Reset Masonry on a small timed event.
*/
app.resetMasonry = function () {
// Allow animation, manually call masonry again
var timeout = setTimeout(function () {
app.$grid.masonry();
//app.trigger('stamp');
clearTimeout(timeout);
}, app.masonryTO);
};
/**
* Watch masonry & window resizing.
*/
app.watch = function watch() {
app.$grid.on('click', '.entry-content, .entry-content .btn.learn', app.entryHandler);
//$(window).on('resize',app.resize);
};
/**
* onResize event callback.
*
* @param event
*/
app.resize = function onResize(event) {
app.removeStyles();
app.createStyle();
};
/**
* Handles click event on non-featured/stamped item to make featured.
*
* @param {object} event jQuery event object.
*/
app.entryHandler = function entryHandler(event) {
var $entry = $(this).parent('.entry');
if ($entry.hasClass('view')) {
return;
}
event.preventDefault();
console.log('click');
if (app.$previousEntry) {
app.unfeature(app.$previousEntry);
}
app.feature($entry);
};
/**
* Toggles featured classes.
*
* @param {obj} $entry jQuery object.
*/
app.toggleFeature = function ($entry) {
$entry.toggleClass('featured double entry--width2 entry--height2');
};
/**
* Makes a grid item (entry) unfeatured.
*
* @param {obj} $entry jQuery object.
*/
app.unfeature = function unfeature($entry) {
var timeout,
$img = $entry.find('img'),
$item = $entry.find(app.itemSelector),
$btn = $entry.find('.btn.view');
// Remove featured classes
app.toggleFeature($entry);
$entry.removeClass('view');
$btn
.addClass('learn').removeClass('view')
.text('Learn More');
$entry.find('.expand .excerpt').remove();
// Allow animation, then replace image classes and image size
timeout = setTimeout(function () {
$entry.addClass('overlay-grey');
$item.addClass('overlay-grey');
$img
.addClass('greyscale filtered')
.attr('src', $img.attr('data-thumb'));
clearTimeout(timeout);
// Allow animation, manually call masonry again
app.resetMasonry();
}, app.resizeTO);
};
/**
* Makes a grid item (entry) featured.
*
* @param {obj} $entry jQuery object.
*/
app.feature = function feature($entry) {
var timeout,
$img = $entry.find('img'),
$item = $entry.find(app.itemSelector),
$btn = $entry.find('.btn.learn');
// Add featured classes
app.toggleFeature($entry);
$entry.addClass('view');
$btn
.removeClass('learn').addClass('view')
.text($btn.attr('data-view'));
$entry.find('.expand .h3').after('<p class="excerpt light ' + $item.attr('data-text-color') + '">' + ( $item.attr('data-content') || 'text-white' ) + '</p>');
// Allow animation, then replace image classes and image size
timeout = setTimeout(function () {
$img
.removeClass('greyscale filtered')
.attr('src', $img.attr('data-featured'));
$entry.removeClass('overlay-grey');
$item.removeClass('overlay-grey');
clearTimeout(timeout);
// Allow animation, manually call masonry again
app.resetMasonry();
app.$previousEntry = $entry;
}, app.resizeTO);
};
// Let's go!!
$(document).ready(app.init);
return app;
})(jQuery, window, document);
代码在网站上运行(在CodePen中,由于某种原因,第一个标记没有正确显示)。但问题是:前两个非印章块出现在邮票下方,而不是在第二个邮票的顶部,如预期的那样。
我相信这是问题所在。印章元素宽度为50%,普通元素宽度为25%。
因此,如果窗口为1583px,则宽度计算为:
app.$grid.find('.entry:not(.stamp)').get(0).getBoundingClientRect().width;
)因此,当砌体进行计算时,一行有四个元素,左边的值是(括号仅指列号,仅供参考):
但如果第一个是特色项目(括号仅指列号仅供参考):
这使宽度 1px 太宽了!我相信这是jQuery在砌体内进行整理的结果。