如何将 Bootstrap Span 元素与 ngRepeat 一起使用
将 Bootstrap Span 元素与 ngRepeat 一起使用的解决方案。
引言
这将是一个简短的教程。我认为,在应用程序中发现一个 bug 是寻找解决方案的最佳动力。最近,我遇到了一个非常小的问题,起初看起来似乎无法解决。当解决方案出现时,它显得如此简单,以至于一开始根本不应该成为一个问题。总之,我认为这个问题及其解决方案值得记录。就我个人而言,我在网上找不到任何解决方案。要么是因为它太简单,要么是因为它对其他人来说太不重要。如果其他人遇到了同样的问题,这个解决方案可以帮助他们。
那么问题是什么呢?想象一下,你有一个 span
元素的列表,它们被 Bootstrap 的 label 类(label
和 label-info
或 label-success
、label-warning
等)装饰。当它们显示在屏幕上时,它们会显示在一行上。当页面调整大小时,它们仍然显示为一行,而不是正确地自动对齐到多行。下面是这个问题看起来的截图。
为什么会出现这个问题?我承认我有点天真。我直接在 span
元素上使用了 ngRepeat
(来自 AngularJS)。这就是我所做的。我坦诚地承认,当时我不知道有更好的方法。我本应该知道得更清楚。
<div class="row">
<div class="col-xs-12">
<span class="label label-info" ng-repeat="item in vm.keywords">{{item}}</span>
</div>
</div>
正如你所见,HTML 标记看起来是合理的。我没有意识到的是,在这种设计下,span
元素会一个接一个地放置,**它们之间没有空格**。而 span
是一个内联元素,这样的元素排列会导致如上图所示的问题。
在“框内”寻找解决方案
我尝试的第一个解决方案是,在 ngRepeat
指令包含其中时,如何为 span
元素添加额外的空格。这是一个非常难用谷歌搜索找到答案的问题。很难找到一个直接的答案。
结果发现,有一个解决方案恰好击中了要害。而且它确实是正确的解决方案。然而,它非常难以寻找,并且这个解决方案隐藏在谷歌搜索结果的第五页。不幸的是,我再也找不到那个页面了。否则,我会给予那位仁兄应有的肯定。总之,我并没有自己想出这个答案。这很棘手,而且我对 HTML5 的了解不足以想出这样的东西。解决方案是在元素末尾附加一个空格字符。当 ngRepeat
在循环中复制该元素时,它将确保元素之间的间距得到妥善管理。这是通过 CSS 实现的。
通过 CSS 和 HTML5,你可以指定在 HTML 元素之后添加内容。所以,这是我在找到的解决方案中定义的 CSS 类:
.space::after {
content: " ";
}
CSS 定义非常简单,对于任何带有“space
”CSS 类的元素,在末尾添加一个空格字符。CSS 中的 content
关键字意味着要添加的样式是文本内容。所以,任何包含在单引号或双引号中的内容都是要添加到元素末尾的文本内容。
这是在解决方案中 ngRepeat
的用法,以及这个新的 CSS 类的使用方法:
<div class="row">
<div class="col-xs-12">
<span class="space" ng-repeat="item in vm.keywords">
<span class="label label-info">{{item}}</span>
</span>
</div>
</div>
下面是 span
元素列表正确对齐并换行的截图。
这里的想法是将 span
元素包装在另一个 span
元素内。额外的空白内容被添加到外部 span
元素的末尾。这确保了 span
元素(外部的)在添加到页面的 DOM 树时具有正确的间距。
这是解决方案 #1,它教会了我两件事:
- 使用 CSS 和 HTML 5,可以轻松地向 HTML 页面添加额外内容。
- 可以将一个
span
元素包装在另一个span
元素内。
第二点是我本应意识到的,但直到有人向我展示解决方案,我才看到。第一点是我真的不知道的。如果我忽略了这个问题,或者只是随便放一个假的解决方案然后忘掉它,我就不会学到这些。所以,每一个 bug,我们试图修复它,都会教会我们一些我们不知道的东西。
既然我知道可以将一个 span
元素包装在另一个 span
元素内,还有其他方法可以解决这个问题吗?结果发现,我不必使用本节中描述的如此复杂的解决方案,也不必使用新的 CSS 类来添加额外的空格。
跳出“框”寻找解决方案
我试图想出的解决方案是某种方式在每个 span
元素后添加一些空格,这样它们就不会“粘在一起”。“框内”解决方案是某种方式给每个 span
元素添加空格。
有了现有的解决方案,我能够实现它。然而,这个解决方案很复杂。除非有人知道如何使用 CSS 中的 content
关键字,否则无法在元素末尾添加空格。如果有人查看这个实现,他们不知道这种设计的意图,那么很可能会有意想不到的更改最终破坏这个实现。
有没有更好的方法来解决原始问题?有。这是我最终想出的实现:
<div class="row">
<div class="col-xs-12">
<span ng-repeat="item in vm.keywords">
<span class="label label-info">{{item}}</span>
</span>
</div>
</div>
你能看出这里的区别吗?我所做的就是移除了外部 span 元素上的 CSS 类“space
”。如果你猜对了,你可能会认为末尾添加的空格是不需要的。当外部 span
执行 ngRepeat
的复制时,最终的 DOM 元素将如下所示:
<div class="row">
<div class="col-xs-12">
<span ... >
<span class="label label-info">{{item #1}}</span>
</span>
<span ... >
<span class="label label-info">{{item #2}}</span>
</span>
<span ... >
<span class="label label-info">{{item #3}}</span>
</span>
<span ... >
<span class="label label-info">{{item #4}}</span>
</span>
<span ... >
<span class="label label-info">{{item #5}}</span>
</span>
<span ... >
<span class="label label-info">{{item #6}}</span>
</span>
...
</div>
</div>
有了这样的 DOM 元素表示,每个 span
元素之间就有足够的空格。因此,使用 CSS 类指定添加的额外空格根本不是必需的。如果我没有想到将一个 span
元素包装在另一个 span
元素中。我可能永远也得不出这个结论。我觉得这是一个“跳出我被困住的框”的解决方案。
下面是三种排列方式的截图。
第一个是有问题的实现。第二个是带有 CSS 类的解决方案。最后一个是我删除了 CSS 类但仍然按预期工作的那个。所以,新的 CSS 类根本不需要。
摘要
就是这样。这是一个简短的教程。本教程的目标很简单。一方面,我只想向你展示,在没有一些包装的情况下使用 ngRepeat
和 span
是一个坏主意。它会导致所有 span
元素都排列在一行上。当页面的整体宽度变小时,它们不会重新对齐到多行。第二个目标是讨论我如何学会使用 CSS 和 HTML 5 添加新的文本内容。这对于未来的项目可能会有用。最后,我学到的教训是,我可以将一个 span
包装在另一个 span
元素内。这允许我在外部 span
元素中使用 ngRepeat
指令,并使用内部 span
元素进行实际的显示装饰。结果发现,包装的 span
实现解决了问题,而无需更复杂的设计(使用 CSS 在 HTML 元素末尾添加空格)。
如果你从未遇到过类似我的问题,那很好。如果你遇到了并已经找到了解决方案,我为你感到非常高兴。但如果你是不幸的那些人之一,遇到了这个问题,并且还没有找到解决方案,请看看这个。我希望它能给你需要的东西。祝你好运!
历史
- 2020年8月23日 - 初稿