javascript - CSS/JS 如果由于先前的元素从流中删除而移动图像的位置,我可以转换图像的位置吗?
问题描述
所以我正在尝试在这个链接中实现一个画廊(点击现场演示并向下滚动)。当用户单击一个按钮时,不在该组中的图像应该缩小并消失,而其他图像应该移动以填补空白。目前我正在使用网格来保存图像。每个图像都是静态定位的,但由 JS 根据它的 offsetTop 和 OffsetLeft 设置顶部和左侧。为了隐藏每个图像,我将它的位置设置为绝对以将其从流中删除并设置 transform: scale(0) ,变换上的过渡效果很好,并且保留的图像重新定位到网格中的正确位置。然而,他们显然会立即做到这一点,这不是我想要的结果。我真的很想为这个项目坚持使用基本的 HTML CSS JS,因为我正在学习很多东西。我只是想知道是否有一个简单的解决方案我'这是我当前的版本,所以你可以看到我在哪里。
这是一些试图解决问题的JS:
//adds galleryButtonClicked function to all gallery buttons
(function() {
let galleryButtons = document.getElementsByClassName("gallery-button");
for (let i = 0; i < galleryButtons.length; i++)
{
galleryButtons[i].addEventListener("click", galleryButtonClicked);
}
})();
//adds top and left to each gallery image that matches it's current position. Declared and called
//seperately as may need to recall on window resize
function setImageAbsCoords() {
let images = document.getElementsByClassName("gallery-image");
for (let image of images)
{
let y = image.offsetTop + "px";
let x = image.offsetLeft + "px";
image.style.top = y;
image.style.left = x;
}
}
setImageAbsCoords();
function galleryButtonClicked() {
//show only group images
if (this.dataset.group == 0)
showAllGalleryImages();
else
showGalleryImagesGroup(this.dataset.group);
}
function showAllGalleryImages() {
let images = document.getElementsByClassName("gallery-image");
for (let image of images)
{
showGalleryImage(image);
}
}
function showGalleryImagesGroup(group) {
let images = document.getElementsByClassName("gallery-image");
for (let image of images)
{
if (image.dataset.group === group)
showGalleryImage(image);
else
hideGalleryImage(image);
}
}
function showGalleryImage(image) {
image.style.position = "static";
image.style.transform = "scale(1)";
}
function hideGalleryImage(image) {
image.style.position = "absolute";
image.style.transform = "scale(0)";
}
和相应的CSS:
gallery-image-container {
display: grid;
margin: 0 auto;
padding: 3rem 0;
width: 80%;
grid-template-columns: repeat(4, 170px);
grid-template-rows: repeat(3, auto);
gap: 20px;
justify-content: center;
}
.gallery-image {
transition : transform 400ms ease-in-out;
}
最后,有问题的html:
<div class="grid gallery-buttons">
<button class="button gallery-button active" data-group="0">All</button>
<button class="button gallery-button" data-group="1">Lorem Ipsum</button>
<button class="button gallery-button" data-group="2">Dolor Sit</button>
<button class="button gallery-button" data-group="3">adipiscing Elit</button>
</div>
<div class="grid gallery-image-container">
<img class="gallery-image" data-group="1" src="https://picsum.photos/170/170?image=0" alt="random demo-gallery-pic">
<img class="gallery-image" data-group="3" src="https://picsum.photos/170/170?image=11" alt="random demo-gallery-pic">
<img class="gallery-image" data-group="1" src="https://picsum.photos/170/170?image=15" alt="random demo-gallery-pic">
<img class="gallery-image" data-group="1" src="https://picsum.photos/170/170?image=18" alt="random demo-gallery-pic">
<img class="gallery-image" data-group="3" src="https://picsum.photos/170/170?image=23" alt="random demo-gallery-pic">
<img class="gallery-image" data-group="2" src="https://picsum.photos/170/170?image=27" alt="random demo-gallery-pic">
<img class="gallery-image" data-group="2" src="https://picsum.photos/170/170?image=30" alt="random demo-gallery-pic">
<img class="gallery-image" data-group="1" src="https://picsum.photos/170/170?image=31" alt="random demo-gallery-pic">
<img class="gallery-image" data-group="3" src="https://picsum.photos/170/170?image=38" alt="random demo-gallery-pic">
<img class="gallery-image" data-group="2" src="https://picsum.photos/170/170?image=42" alt="random demo-gallery-pic">
<img class="gallery-image" data-group="2" src="https://picsum.photos/170/170?image=55" alt="random demo-gallery-pic">
<img class="gallery-image" data-group="1" src="https://picsum.photos/170/170?image=69" alt="random demo-gallery-pic">
</div>
解决方案
好的,所以我实际上想通了。我已经包含了一个 jsfiddle来演示它是否正常工作。只需在关闭转换的情况下将图像转换回其初始位置,然后在重新打开转换时将转换设置为无。感谢任何花时间阅读本文的人。
//adds galleryButtonClicked function to all gallery buttons
(function() {
let galleryButtons = document.getElementsByClassName("gallery-button");
for (let i = 0; i < galleryButtons.length; i++)
{
galleryButtons[i].addEventListener("click", galleryButtonClicked);
}
})();
//adds top and left to each gallery image that matches it's current position. Declared and called
//seperately as may need to recall on window resize
function setImageAbsCoords() {
let images = document.getElementsByClassName("gallery-image");
for (let image of images)
{
//for later do not update if already set to absolute position
if (image.style.position !== "absolute")
{
let y = image.offsetTop + "px";
let x = image.offsetLeft + "px";
image.style.top = y;
image.style.left = x;
}
}
}
setImageAbsCoords();
function galleryButtonClicked() {
//gather images old positions
let images = document.getElementsByClassName("gallery-image");
console.log(images.length);
for (let image of images)
{
image.dataset.oldposx = image.offsetLeft;
image.dataset.oldposy = image.offsetTop;
}
//show only group images
if (this.dataset.group == 0)
showAllGalleryImages();
else
showGalleryImagesGroup(this.dataset.group);
let staticImages = Array.from(images).filter(img => img.style.position === "static");
transitionRemainingImagesToNewPos(staticImages);
}
function showAllGalleryImages() {
let images = document.getElementsByClassName("gallery-image");
for (let image of images)
{
showGalleryImage(image);
}
}
function showGalleryImagesGroup(group) {
let images = document.getElementsByClassName("gallery-image");
for (let image of images)
{
if (image.dataset.group === group)
showGalleryImage(image);
else
hideGalleryImage(image);
}
}
function showGalleryImage(image) {
//set wasHidden flag for transitionRemainingImagesToNewPost to reset scale before turning off transitions
if (image.style.position === "absolute")
image.dataset.wasHidden = true;
else
image.dataset.wasHidden = false;
image.style.position = "static";
image.style.transform = "scale(1)";
}
function hideGalleryImage(image) {
image.style.position = "absolute";
image.style.transform = "scale(0)";
}
function transitionRemainingImagesToNewPos(images) {
for (let image of images)
{
//turn off transitions
image.classList.add("no-transition");
//move back to old position before gallery reshaped after button press
diffx = image.dataset.oldposx - image.offsetLeft;
diffy = image.dataset.oldposy - image.offsetTop;
image.style.transform = `translate(${diffx}px, ${diffy}px)`;
//set scale back to 0 if had been hidden before now
if (image.dataset.wasHidden === 'true')
image.style.transform += ` scale(0)`;
image.offsetHeight; //force a redraw
image.classList.remove("no-transition");
image.style.transform = "none";
}
//update top and left to new position
setImageAbsCoords();
}
推荐阅读
- ios - 编码中的日期格式问题不适用于解码器
- nd4j - nd4j 中的矩阵乘法广播
- elasticsearch - 在两个 Elasticsearch 服务器之间传输一个分片或索引
- python - 如何查看空字典?
- sql - How to increase fetching speed of large data in SQL Server
- html - 如何使 EmailId 验证器忽略角度 6 中的大小写?
- azure - 将文件从 Spark 写入 CosmosDB 的问题
- sql-server - 将文件存储在数据库服务器中作为 FILESTREAM
- javascript - 仅显示样式一段时间然后删除
- javascript - 减少 CSS 样式