【问题标题】:Dynamically flexible width & number items with flex动态灵活的宽度和数量项目与 flex
【发布时间】:2021-02-10 23:33:04
【问题描述】:

我有一组标签,我想在客户端显示。但是,有时您可能有太多标签,并且您希望仅显示一行标签最大化到您的身体宽度,而不设置固定数量的列数或项目宽度,并在标签列表末尾添加一个显示更多按钮与标签相同的样式。

我在我的 Angular 项目中使用 Javascript 实现了这一点,方法是:

  1. 在我的内容容器上使用 ViewChild 动态找出标签容器的宽度:

let contentWidth = this.contentContainer.nativeElement.clientWidth;

  1. 计算查看更多按钮的文本宽度,并用它计算新的内容宽度减去查看更多按钮宽度:

计算文本函数执行以下操作:

  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;

  1. 创建一个新的数组变量“previewTags”,该变量将保存标签主体处于折叠状态时可见的标签,并通过计算每个标签的宽度以及您从API 通过检查下一个标签及其填充(静态值)是否适合宽度。

(此处不可运行)

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;
    }
}
  1. 点击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>

输出:

调整大小:

如您所见,现在标签是灵活的(此代码不包括显示更多功能)。

在向您介绍了这些背景并了解了我的工作之后,我想问一下这是否可以通过 css 或更少的 JavaScript 干预来实现?

【问题讨论】:

  • 只有 CSS 的解决方案是让标签容器在标签超过容器宽度时水平滚动。

标签: javascript css angular


【解决方案1】:

如果你的标签有一个恒定的高度,这样的东西可能是一个纯粹的 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 发布了另一个答案来修复它。不知道这是不是最好的方法,但它可以工作:)(单击“整页”按钮并调整演示窗口的大小)
【解决方案2】:

如果不需要,这里有一些 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-22
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多