有没有办法确保所有元素在再次操作之前已重置到原始位置?

问题描述 投票:1回答:2

首先,我知道这是一个很大的问题。我正在寻找更多的想法和指导,而不是完整的解决方案。我正在建立一个在屏幕上有十张牌的网站。每张卡与前一张卡略有重叠。当鼠标放在卡片上时,其他卡片应该移开,突出显示的卡片应该展开。是否有办法使光盘移出当前卡并开始任何其他操作之前所有卡都返回到原始位置?我已经包含了我当前.html文件中的所有代码。

我已经尝试在HTML文档上使用onMouseOver和onMouseOut来根据调用的函数来回移动元素。

我试着在时间线课上搞乱GSAP,但我无法弄清楚如何制作一个我可以播放,停止,反转等动画。

我目前已经设置了添加和删除事件监听器的超时,以限制函数调用的速度。

var cards = document.getElementsByClassName('card');
var currentCard;
var currentIndex;
var leftSpread = 150;
var rightSpread = 200;
var initialOffset = 100;

(function initialLoad() {
  for (var i = 0; i < cards.length; i++) {
    cards[i].style.zIndex = i;

    cards[i].addEventListener("mouseenter", this);

    if (i > 0) {
      cards[i].style.left = cards[i - 1].offsetLeft + initialOffset + 'px';
    }
  }
})();

function handleEvent(evt) {
  switch (evt.type) {
    case "mouseenter":
      this.cardMouseOver(evt);
      break;
    case "mouseout":
      this.cardMouseOut(evt);
      break;
    default:
      return;
  }
}

function cardMouseOver(event) {
  currentIndex = event.target.style.zIndex;
  event.target.style.zIndex = 10;

  for (var i = 0; i < cards.length; i++) {
    if (event.target == cards[i]) {
      currentCard = i;
    } else {
      cards[i].removeEventListener("mouseenter", this);
    }
  }

  setTimeout(function() {
    cards[currentCard].addEventListener("mouseout", this);
  }, 50);

  for (var i = 0; i < cards.length; i++) {
    if (i < currentCard) {
      cards[i].style.left = cards[i].offsetLeft - leftSpread + 'px';
    } else if (i > currentCard) {
      cards[i].style.left = cards[i].offsetLeft + rightSpread + 'px';
    }
  }

  cards[currentCard].removeEventListener("mouseenter", this);
}

function cardMouseOut(event) {
  cards[currentCard].style.zIndex = currentIndex;

  setTimeout(function() {
    for (var i = 0; i < cards.length; i++) {
      cards[i].addEventListener("mouseenter", this);
    }
  }, 100);

  for (var i = 0; i < cards.length; i++) {
    if (i === currentCard) {
      cards[i].removeEventListener("mouseout", this);
    }
  }

  for (var i = 0; i < cards.length; i++) {
    if (i < currentCard) {
      cards[i].style.left = cards[i].offsetLeft + leftSpread + 'px';
    } else if (i > currentCard) {
      cards[i].style.left = cards[i].offsetLeft - rightSpread + 'px';
    }
  }
}
body {
  background-color: #242424;
  padding: 0;
  margin: 0;
}

.cards-container {
  background: #fff;
  margin: 20px auto;
  position: absolute;
  left: 21%;
  top: 375px;
}

.card {
  position: absolute;
  background: rgb(255, 255, 255);
  border: 1px solid black;
  height: 250px;
  transition: 0.2s;
  width: 200px;
  box-shadow: -1px 0px 1px 1px rgba(0, 0, 0, 0.747);
}

.card:hover {
  transition: all 0.2s ease;
  width: 250px;
  height: 350px;
  top: -75px;
}
<body>
  <header>
    <div class="cards-container">
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
      <div class="card"></div>
    </div>
  </header>
</body>

<script type="text/javascript" src="http://code.jquery.com/jquery-3.4.0.min.js"></script>

我希望所有内容都根据当前突出显示的卡片(平滑过渡)进行定位,并在没有突出显示任何内容时重置为原始位置。

javascript html css dom
2个回答
0
投票

有几种方法可以做到这一点

  1. 你可以有一个布尔标志,当元素移动/移出时,它会切换。从那里,您可以在元素返回其起始位置时重新切换它。
let DOMHasChanged = false

function handleEvent(evt) {
  DOMHasChanged = true
  switch (evt.type) {
    case "mouseenter":
      this.cardMouseOver(evt);
      break;
    case "mouseout":
      this.cardMouseOut(evt);
      break;
    default:
      return;
  }
}

// Some function to set DOMHasChanged back to false on element reset
  1. 您可以通过类(.inUse,.active,.hovered等)处理动画和CSS更改,然后运行一个循环来检查是否有任何元素具有“活动”类
const pageChanged = () => {
  if(Array.from(document.querySelectorAll(".inUse")).length > 0) {
    return false
  } else {
    return true
  }
}

编辑:此外,关于动画,当你知道如何时,它们相当简单!我建议你看看W3Schools关于@keyframes的文章

https://www.w3schools.com/cssref/css3_pr_animation-keyframes.asp

您还可以将动画方向设置为前进,后退等。它非常强大!


0
投票

我能够通过继续挖掘找到答案。它比我想象的要简单得多。因为当用鼠标悬停卡片时我想要一个平滑的动画,我使用了CSS过渡和变换属性。

通过创建这些CSS类:

.card {
    position: absolute;
    background: rgb(255, 255, 255);
    height: 275px;
    width: 200px;
    box-shadow: -1px 0px 3px 1px rgba(0, 0, 0, 0.747);
    transition: all .4s ease;
}

.card.left {
    transform: translateX(-175px);
}

.card.right {
    transform: translateX(175px);
}

我能够在“mouseenter”和“mouseover”事件监听器中添加和删除它以获得我正在寻找的效果。

function handleEvent(evt) {
    switch(evt.type) {
        case "mouseenter":
            this.cardMouseOver(evt);
            break;
        case "mouseout":
            this.cardMouseOut(evt);
            break;
        default:
            return;
    }
}

function cardMouseOver(event) {
    for (var i = 0; i < cards.length; i++) {
        if (event.target == cards[i]) {
            currentCard = i;
        }
    }

    for (var i = 0; i < cards.length; i++) {
        if (i < currentCard) {
            if (!cards[i].classList.contains('left')) {
                cards[i].classList.add('left');
            }
        } else if (i > currentCard) {
            if (!cards[i].classList.contains('right')) {
                cards[i].classList.add('right');
            }
        }
    }
}

function cardMouseOut(event) {
    for (var i = 0; i < cards.length; i++) {
        if (i < currentCard) {
            if (cards[i].classList.contains('right')) {
                cards[i].classList.remove('right');
            } else if (cards[i].classList.contains('left')) {
                cards[i].classList.remove('left');
            }
        } else if (i > currentCard) {
            if (cards[i].classList.contains('left')) {
                cards[i].classList.remove('left');
            } else if (cards[i].classList.contains('right')) {
                cards[i].classList.remove('right');
            }
        } else {
            if (cards[i].classList.contains('left')) {
                cards[i].classList.remove('left');
            } else if (cards[i].classList.contains('right')) {
                cards[i].classList.remove('right');
            }
        }
    }
}

卡片是“卡片”元素的数组。

© www.soinside.com 2019 - 2024. All rights reserved.