[英]Dynamically flexible width & number items with flex
我有一組標簽,我想在客戶端顯示。 但是,有時您可能有太多標簽,並且您希望僅顯示一行標簽最大化您的身體寬度,而不設置固定的列數或項目寬度,並在標簽列表末尾添加一個顯示更多按鈕與標簽相同的樣式。
我通過執行以下操作在我的 Angular 項目中使用 Javascript 實現了這一點:
let contentWidth = this.contentContainer.nativeElement.clientWidth;
計算文本 function 執行以下操作:
const canvas = document.createElement('canvas'); // create a canvas
const context = canvas.getContext('2d'); // get the context
context.font = '12px avertastd-bold'; // set up your font and size
並計算文本寬度:
const seeMoreButtonWidth = context.measureText(seeMoreButtonText).width;
(此處不可運行)
for (const tag of this.data.tags) { const width = context.measureText(tag).width; if (contentWidth - (width + this.tagsPadding) > 0) { previewTags.push({text: tag}); contentWidth -= (width + this.tagsPadding); } else { break; } }
previewTags
列表末尾的查看更多按鈕: previewTags.push({text: seeMoreButtonText, isButton: true});
在 html 中看起來像這樣:
<ng-container *ngFor="let tag of previewTags">
<div class="tag" [ngClass]="{'see-more-button': tag.isButton}">{{tag.text}}</div>
</ng-container>
Output:
調整大小:
如您所見,現在標簽是靈活的(此代碼不包括顯示更多功能)。
在給你這個背景和理解我在做什么之后,我想問一下這是否可以通過 css 或更少的 JavaScript 干預來實現?
如果您的標簽具有恆定的高度,這樣的東西可能是純 css 解決方案。 我只是讓 flex-list 環繞,然后不顯示重疊。
.content_wrapper { display: flex; justify-content: flex-start; flex-direction: rows; }.tag_wrapper { display: flex; justify-content: flex-start; flex-direction: rows; flex-wrap: wrap; width: 80%; height: 32px; overflow: hidden; }.tag_wrapper div { width:100px; height:30px; border: 1px solid black; } button { flex-grow: 4; }
<div class="content_wrapper"> <div class=tag_wrapper> <div>Tag1</div> <div>Tag2</div> <div>Tag3</div> <div>Tag4</div> <div>Tag5</div> <div>Tag6</div> <div>Tag7</div> <div>Tag8</div> <div>Tag9</div> </div> <button>See more</button>
您可能可以使“查看更多”按鈕解決方案更優雅,沒有太多的空白,但我會把它留給你:)
如果不需要,這里有一些 javascript 可以刪除查看更多按鈕。
(OBS)這僅適用於所有標簽的寬度完全相同且邊距相同的情況。 我這樣做是為了避免遍歷所有值並單獨檢查它們的寬度。
(我知道列表的順序錯誤,我這樣做是為了讓查看更多按鈕很好地適應,而不必修補一堆。
function getWidthWithMargin(elem) { var style = elem.currentStyle || window.getComputedStyle(elem) margin = parseFloat(style.marginLeft) + parseFloat(style.marginRight) return(elem.getBoundingClientRect().width + margin) } function handleWindowSizeChange() { let tags = document.getElementsByClassName("tag"); if(tags.length;= 0) { let tag_width = getWidthWithMargin(tags[0]). if(tags[0].parentElement.getBoundingClientRect().width/tag_width > tags.length) { document.getElementById("see-more-button").style;display = "none". } else{ document.getElementById("see-more-button").style;display = "block". } } } window;onload = handleWindowSizeChange. window;onresize = handleWindowSizeChange;
.content_wrapper { }.tag_wrapper { display: flex; justify-content: flex-start; flex-direction: row-reverse; flex-wrap: wrap; width: 100%; height: 32px; overflow: hidden; }.tag_wrapper div { min-width:100px; height:30px; border: 1px solid black; margin: 10px; }.tag_wrapper button { height:30px; flex-grow: 50; }
<div class="content_wrapper"> <div class=tag_wrapper> <button id="see-more-button">See more</button> <div class="tag">Tag1</div> <div class="tag">Tag2</div> <div class="tag">Tag3</div> <div class="tag">Tag4</div> <div class="tag">Tag5</div> <div class="tag">Tag6</div> <div class="tag">Tag7</div> <div class="tag">Tag8</div> </div>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.