公司最近在重構,使用的是Vue框架。涉及到一個品牌的佈局,由於品牌的字符長度不一致,因此致使每個的品牌標籤長短不一。多行佈局下就會致使每行的品牌佈局良莠不齊,嚴重影響美觀。因而就有了本篇的木桶佈局插件。vue
首先獲取咱們須要的元素、和咱們目標容器的寬度。git
Vue組件容器:github
<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'; } })
}npm
我這邊是採用的平均分配的方式將多餘的寬度平均分配到每個元素裏。如一行中所有元素佔800px,有8個元素,該行總長爲960px。則每行增長的寬度爲(960-800)/8=16,每一個與元素寬度增長16px;
值得注意的是,js在獲取元素寬度的時候會存在精度問題,因此須要進行預設一個像素進行緩衝。框架
Github:vue-barrel佈局
npm: vue-barrelthis