html - 如果它是从 JS 构建的,如何在调整大小事件后重建 DOM
问题描述
我正在一个实施砖石画廊的项目中工作。它工作得很好,但我需要在 JS 构造调用中动态调整列的数量......我尝试了不同的方法来调整大小事件、while 循环、条件 if ,甚至从 CSS 使用 mediaQueries 破解列号,一无所有,递归调用和无限循环,我还找不到解决方案......
const masonryLayout = (containerElem, itemsElems, columns) => {
// Crea Container para las columnas
containerElem.classList.add('masonry-layout', `columns-${columns}`)
// Crea n-columnas de acuerdo a "columns"
let columnsElements = []
for (let i = 1; i <= columns; i++) {
let column = document.createElement('div')
column.classList.add('masonry-column', `column-${i}`)
containerElem.appendChild(column)
columnsElements.push(column)
}
// Ubica cada imagen en la columna correspondiente
for (let m = 0; m < Math.ceil(itemsElems.length / columns); m++) {
for (let n = 0; n < columns; n++) {
let item = itemsElems[m * columns + n]
columnsElements[n].appendChild(item)
item.classList.add('masonry-item')
}
}
}
masonryLayout(document.getElementById("gallery"), document.querySelectorAll(".gallery-item"),5)
.gallery-item img {
max-width: 100%;
display: block;
}
.masonry-layout {
--columns: 5;
--gap: 0.6rem;
display: grid;
grid-template-columns: repeat(var(--columns), 1fr);
grid-gap: var(--gap);
}
.masonry-layout .masonry-item {
margin-bottom: var(--gap);
}
.masonry-layout.columns-1 {
--columns: 1;
}
.masonry-layout.columns-2 {
--columns: 2;
}
.masonry-layout.columns-3 {
--columns: 3;
}
.masonry-layout.columns-4 {
--columns: 4;
}
.masonry-layout.columns-5 {
--columns: 5;
}
<div class="gallery" id="gallery">
<div class="columnNbrClass"></div>
<div class="gallery-item">
<img src="https://picsum.photos/450/325?image=100" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/450?image=200" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/280?image=300" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/540?image=400" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/380?image=500" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/300?image=600" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/400?image=700" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/300?image=800" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/280?image=900" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/480?image=925" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/550?image=950" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/600?image=1000" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/325?image=25" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/450?image=50" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/280?image=75" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/540?image=100" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/380?image=125" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/300?image=161" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/400?image=175" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/300?image=200" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/280?image=225" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/480?image=250" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/550?image=275" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/600?image=300" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/325?image=13" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/450?image=26" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/280?image=39" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/540?image=52" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/380?image=65" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/300?image=78" alt="" class="">
</div>
</div>
基本上,我需要 masonryLayout 构造函数中的列号在调整大小时动态更改,但我找不到方法,我什至尝试保存原始 html 文档但没有任何运气......如果有人有任何想法,它会很高兴听到和学习。
非常感谢您的交流!
解决方案
不确定这是否是您想要的,但如果您只是想要一个可调整大小的砖石画廊,您可以使用 js 来实现它。如果您使用 js 动态添加项目,它也可以工作。
为了测试调整大小的行为,只需在这个小提琴中调整输出面板的大小: JsFiddle Example
解释:
使用带有 min-width 的媒体查询将随着窗口大小的增加而增加列数,其余的将由网格布局完成。用 js 添加内容会强制浏览器重新渲染,所以应该不是问题。
这是一个没有js的工作示例,只有css:
.gallery-item img {
max-width: 100%;
display: block;
}
.masonry-layout {
--columns: 1;
--gap: 0.6rem;
columns: var(--columns);
grid-gap: var(--gap);
}
.masonry-layout .masonry-item {
margin-bottom: var(--gap);
display: inline-block;
}
@media only screen and (min-width: 300px) {
.masonry-layout {
--columns: 2;
}
}
@media only screen and (min-width: 500px) {
.masonry-layout {
--columns: 3;
}
}
@media only screen and (min-width: 800px) {
.masonry-layout {
--columns: 4;
}
}
@media only screen and (min-width: 1000px) {
.masonry-layout {
--columns: 5;
}
}
<div class="gallery masonry-layout" id="gallery">
<div class="gallery-item">
<img src="https://picsum.photos/450/325?image=100" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/450?image=200" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/280?image=300" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/540?image=400" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/380?image=500" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/300?image=600" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/400?image=700" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/300?image=800" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/280?image=900" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/480?image=925" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/550?image=950" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/600?image=1000" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/325?image=25" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/450?image=50" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/280?image=75" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/540?image=100" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/380?image=125" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/300?image=161" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/400?image=175" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/300?image=200" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/280?image=225" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/480?image=250" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/550?image=275" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/600?image=300" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/325?image=13" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/450?image=26" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/280?image=39" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/540?image=52" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/380?image=65" alt="" class="">
</div>
<div class="gallery-item">
<img src="https://picsum.photos/450/300?image=78" alt="" class="">
</div>
</div>
[编辑]
也看看这个小提琴
我使用你的代码并修改它以在再次填充之前清除容器并添加一个onresize,它似乎工作。您的错误之一是未清除所有已设置的类,因此在column.classList.add('masonry-column',
column-${i}中);
添加了两个类,但最后添加的类仍然存在,因此当您以 1 和 2 作为列调用方法 2 次时参数,您将有以下类声明:
1:
class="masonry-column column-1"
2:
class="masonry-column column-1 column-2"
现在,当您缩小窗口时,第 2 列仍然存在,您将显示两列,但只有一列被填充。为了解决这个异常,我添加containerElem.className = ''
了在设置之前清除类。
您的第二个问题是:
Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
在您的情况下,您有 30 个项目,并且您尝试向每个列添加相同数量的项目,这适用于 1、2 和 3 列,因为 30 可以除以每个数字,但对于 4这是不可能的,即使在所有列之间也没有足够的项目来拆分它们。为防止出现错误,您只需检查是否有剩余物品:
if(m*columns + n >= itemsElems.length){
continue;
}
这是一个更新的小提琴,修复了两个错误。
推荐阅读
- linux - 在不使用 sleep 命令的情况下查找长时间运行的作业的经过时间或持续时间
- azure - 在 AAD 中注册的应用程序被拒绝 Azure 存储帐户访问
- c - 使用逻辑或关系运算符对 3 位数进行素性测试
- java - 如何计算给定代码的复杂度
- python - 将数值和分类数据混合到具有密集层的 keras 序列模型中
- docker - Marathon/Mesos - deploy application using the same host port for both UDP and TCP
- listview - 有没有办法解决电视的 Xamarin.Forms Tizen ListView rowheight 属性限制?
- python - 熊猫:比较连续的行
- json - Flutter: Execute a function on Startup - wait for HTTP response parser to extract image URL
- javascript - Possibility about conditional export ES6 module based on process.env.NODE_ENV?