[英]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.