公司最近在重構,使用的是Vue框架。涉及到一個品牌的佈局,因為品牌的字元長度不一致,所以導致每一個的品牌標籤長短不一。多行佈局下就會導致每行的品牌佈局參差不齊,嚴重影響美觀。於是就有了本篇的木桶佈局外掛。
木桶佈局的實現是這樣分步驟的:
- 首先對要填放的內容進行排序,篩選出每一行的元素。
- 再對每一行元素進行修整,使其美觀對齊。
分步驟
一、根據需要選出每行的元素
首先獲取我們需要的元素、和我們目標容器的寬度。
Vue元件容器:
<template>
<div ref="barrel">
<slot></slot>
</div>
</template>
複製程式碼
二、再者我們需要獲取容器和容器寬度
this.barrelBox = this.$refs.barrel;
this.barrelWidth = this.barrelBox.offsetWidth;
複製程式碼
三、接著迴圈我們的元素,根據不同的元素的寬度進行分組。
ps:對於元素的寬度獲取的時候我們需要對盒模型進行區分。
Array.prototype.forEach.call(items, (item) => {
paddingRight = 0;
paddingLeft = 0;
marginLeft = parseInt(window.getComputedStyle(item, "").getPropertyValue('margin-left'));
marginRight = parseInt(window.getComputedStyle(item, "").getPropertyValue('margin-right'));
let boxSizing = window.getComputedStyle(item, "").getPropertyValue('box-sizing');
if (boxSizing !== 'border-box') {
paddingRight = parseInt(window.getComputedStyle(item, "").getPropertyValue('padding-right'));
paddingLeft = parseInt(window.getComputedStyle(item, "").getPropertyValue('padding-left'));
}
widths = item.offsetWidth + marginLeft + marginRight + 1;
item.realWidth = item.offsetWidth - paddingLeft - paddingRight + 1;
let tempWidth = rowWidth + widths;
if (tempWidth > barrelWidth) {
dealWidth(rowList, rowWidth, barrelWidth);
rowList = [item];
rowWidth = widths;
} else {
rowWidth = tempWidth;
rowList.push(item);
}
})
複製程式碼
四、接著是對每一組的元素進行合理分配。
const dealWidth = (items, width, maxWidth) => {
let remain = maxWidth - width;
let num = items.length;
let remains = remain % num;
let residue = Math.floor(remain / num);
items.forEach((item, index) => {
if (index === num - 1) {
item.style.width = item.realWidth + residue + remains + 'px';
} else {
item.style.width = item.realWidth + residue + 'px';
}
})
複製程式碼
}
我這邊是採用的平均分配的方式將多餘的寬度平均分配到每一個元素裡。如一行中全部元素佔800px,有8個元素,該行總長為960px。則每行增加的寬度為(960-800)/8=16,每個與元素寬度增加16px;
值得注意的是,js在獲取元素寬度的時候會存在精度問題,所以需要進行預設一個畫素進行緩衝。
以下是我的程式碼地址
Github:vue-barrel
npm: vue-barrel