JS/CSS将CSS转换应用于已经转换的元素,而不会丢失原始转换

h7appiyu  于 2023-05-02  发布在  其他
关注(0)|答案(1)|浏览(74)

我正在制作一些卡片和动作,作为几个项目的起点。我在试着摇牌的时候遇到了一个问题。因为卡片已经被翻转过了,当我把它左右移动时,它会在震动时移去翻转。
我已经把问题代码放在这个Fiddle中了。点击两张牌来翻转它们,点击一张来选择它(向上移动),然后点击第二张使它摇动(显示未被选择),背面显示而不是正面。
我尝试过使用z索引、不透明度、显示和复制动画中旋转的180度。
我得到的最接近的是使用:不,但它只摇了卡中的文字,而不是整张卡
任何帮助将不胜感激。
TIA
Fiddle代码:

let selectLimit = parseInt(document.getElementById("numSelectLimit").value);
let currentlySelected = [];

function onInput() {
  selectLimit = parseInt(document.getElementById("numSelectLimit").value);
}

function clickFlip4(element) {
  element.classList.toggle("cardFlipped");
  element.setAttribute("onclick", "clickSelect3(this)");
}

function clickSelect3(element) {
  if (element.classList.contains("selected3")) {
    var newArray = [];
    for (var i = 0; i < currentlySelected.length; i++) {
      if (currentlySelected[i] === element) continue;
      else newArray[newArray.length] = element;
    }
    currentlySelected = newArray;
    element.classList.toggle("selected3");
  } else {
    if (currentlySelected.length !== selectLimit) {
      currentlySelected[currentlySelected.length] = element;
      element.classList.toggle("selected3");
    } else {
      element.classList.toggle("shake");
      setTimeout(function() {
        element.classList.toggle("shake");
      }, 500); //500 matches animation length of .05 seconds    
    }
  }
}
.card {
  background-color: transparent;
  width: 275px;
  height: 400px;
  perspective: 1000px;
  /* Remove this if you don't want the 3D effect */
  display: inline-block;
  /*
    padding-top: 65px;
    padding-bottom: 65px;
*/
  padding: 65px 3px;
}

/* This container is needed to position the front and back side */

.cardInner {
  position: relative;
  width: 100%;
  height: 100%;
  text-align: center;
  transition: transform 0.8s;
  transform-style: preserve-3d;
  border-radius: 15px;
}

.cardFlipped {
  transform: rotateY(180deg);
}

/* Position the front and back side */

.cardBack,
.cardFront {
  position: absolute;
  width: 100%;
  height: 100%;
  -webkit-backface-visibility: hidden;
  /* Safari */
  backface-visibility: hidden;
  border-radius: 15px;
  border: 3px solid #000000;
}

/* Style the front side (fallback if image is missing) */

.cardBack {
  background-color: #ffffff;
  color: black;
}

/* Style the back side */

.cardFront {
  background-color: dodgerblue;
  color: white;
  transform: rotateY(180deg);
}

.selected,
.selected2,
.selected3 {
  margin-top: -60px;
}

form,
label,
input {
  font: inherit;
}

.shake {
  animation: horizontal-shaking 0.5s;
}

@keyframes horizontal-shaking {
  0% {
    transform: translateX(0)
  }
  20% {
    transform: translateX(5px)
  }
  40% {
    transform: translateX(-5px)
  }
  60% {
    transform: translateX(5px)
  }
  80% {
    transform: translateX(-5px)
  }
  100% {
    transform: translateX(0)
  }
}
<body>

  <form onsubmit="return false">
    <label for="selectLimit"> Select Limit:</label>
    <input id="numSelectLimit" name="selectLimit" type="number" min="1" max="100" value="1" oninput="onInput()">
  </form>

  <div class="card">
    <div class="cardInner" onclick="clickFlip4(this)">
      <div class="cardBack">
        <p>BACK</p>
      </div>
      <div class="cardFront">
        <p>FRONT</p>
      </div>
    </div>
  </div>
  <div class="card">
    <div class="cardInner" onclick="clickFlip4(this)">
      <div class="cardBack">
        <p>BACK</p>
      </div>
      <div class="cardFront">
        <p>FRONT</p>
      </div>
    </div>
  </div>
</body>
8yoxcaq7

8yoxcaq71#

这是一个恼人的情况。具有transform属性的其他类将重写前一个转换,从而无法实现所需的结果。
但是,我们有几种方法可以解决这个问题:
1.把包起来。cardInner元素,并将抖动动画应用于该 Package 器。或,
1.第二种方法需要对负责翻转的函数进行一些修改。
在翻转卡片之前:显示BACK元素。
翻转动画完成后:删除所有过渡并仅显示FRONT元素。
这将允许您应用新的摇动动画,因为您最终可以只关注当前显示的元素。
只需将clickFlip4()更新为以下内容:

function clickFlip4(element) {
    element.classList.toggle("cardFlipped");
    element.removeAttribute("onclick");
    element.addEventListener('transitionend', () => {

        let back  = element.querySelector('.cardBack');
        let front = element.querySelector('.cardFront');

        back.style.display = "none";
        front.style.transform = "none";

        element.style.transitionDuration = "0s";
        element.style.transform = "none";
        element.setAttribute("onclick", "clickSelect3(this)");

    }, { once: true });
}

以下是代码片段,以防万一:

let selectLimit = parseInt(document.getElementById("numSelectLimit").value);
let currentlySelected = [];

function onInput() {
    selectLimit = parseInt(document.getElementById("numSelectLimit").value);
}

function clickFlip4(element) {
    element.classList.toggle("cardFlipped");
    element.removeAttribute("onclick");
    element.addEventListener('transitionend', () => {

        let back  = element.querySelector('.cardBack');
        let front = element.querySelector('.cardFront');

        back.style.display = "none";
        front.style.transform = "none";

        element.style.transitionDuration = "0s";
        element.style.transform = "none";
        element.setAttribute("onclick", "clickSelect3(this)");

    }, { once: true });
}

function clickSelect3(element) {
    if (element.classList.contains("selected3")) {
        var newArray = [];
        for (var i = 0; i < currentlySelected.length; i++) {
            if (currentlySelected[i] === element) continue;
            else newArray[newArray.length] = element;
        }
        currentlySelected = newArray;
        element.classList.toggle("selected3");
    }
    else {
        if (currentlySelected.length !== selectLimit) {
            currentlySelected[currentlySelected.length] = element;
            element.classList.toggle("selected3");
        }
        else {
            element.classList.toggle("shake");
            setTimeout( function() {
                element.classList.toggle("shake");
            }, 500);         //500 matches animation length of .05 seconds  
        }
    }
}
.card {
    background-color: transparent;
    width: 275px;
    height: 400px;
    perspective: 1000px; /* Remove this if you don't want the 3D effect */
    display: inline-block;
/*
    padding-top: 65px;
    padding-bottom: 65px;
*/
    padding: 65px 3px;
}

/* This container is needed to position the front and back side */
.cardInner {
    position: relative;
    width: 100%;
    height: 100%;
    text-align: center;
    transition: transform 0.8s;
    transform-style: preserve-3d;
    border-radius: 15px;
}

.cardFlipped {
    transform: rotateY(180deg);
}

/* Position the front and back side */
.cardBack, .cardFront {
    position: absolute;
    width: 100%;
    height: 100%;
    -webkit-backface-visibility: hidden; /* Safari */
    backface-visibility: hidden;
    border-radius: 15px;
    border: 3px solid #000000;
}

/* Style the front side (fallback if image is missing) */
.cardBack {
    background-color: #ffffff;
    color: black;
}

/* Style the back side */
.cardFront {
    background-color: dodgerblue;
    color: white;
    transform: rotateY(180deg);
}

.selected, .selected2, .selected3 {
    margin-top: -60px;
}

form, label, input {
    font: inherit;
}

.shake {
    animation: horizontal-shaking 0.5s;
}
    @keyframes horizontal-shaking {
        0% { transform: translateX(0) }
        20% { transform: translateX(5px) }
        40% { transform: translateX(-5px) }
        60% { transform: translateX(5px) }
        80% { transform: translateX(-5px) }
        100% { transform: translateX(0) }
}
<form onsubmit="return false">
  <label for="selectLimit"> Select Limit:</label>
  <input id="numSelectLimit" name="selectLimit" type="number" min="1" max="100" value="1" oninput="onInput()">
</form>

<div class="card">
  <div class="cardInner" onclick="clickFlip4(this)">
    <div class="cardBack">
      <p>BACK</p>
    </div>
    <div class="cardFront">
      <p>FRONT</p>
    </div>
  </div>
</div>
<div class="card">
  <div class="cardInner" onclick="clickFlip4(this)">
    <div class="cardBack">
      <p>BACK</p>
    </div>
    <div class="cardFront">
      <p>FRONT</p>
    </div>
  </div>
</div>

相关问题