某些位置的内联元素样式的奇怪转换行为

时间:2018-04-11 23:14:45

标签: javascript css

这是一个复制问题的jsfiddle示例文件: https://jsfiddle.net/Lhr0d6cw/11/

我希望元素(单击时)从原始位置展开6秒,但请注意,当您单击红色卡片(或任何卡片)时,它不会从原来的位置开始展开,但是而是从中间开始,我认为是因为transition 6s到topleft由于某种原因没有被应用。

到目前为止,我能够使其正常工作的地方是下面的stackoverflow编辑器,或者通过在代码中插入调试器并手动执行它,但是当使用我的localhost或jsfiddle时它不能正常转换。

这是stackoverflow上的相同示例,可以按预期工作:

const productCards = document.querySelectorAll(".products__card");

productCards.forEach(c => {
  // console.log("clicked1");
  c.addEventListener("click", openCard)
});

function openCard(e) {

  console.log("clicked");
  console.dir(this);
  let top = this.getBoundingClientRect().top;
  let left = this.getBoundingClientRect().left;
  // this.style.transition = "top 0.9s, left 0.9s";
  this.style.top = top + "px";
  this.style.left = left + "px";
  this.style.position = "fixed";
  console.log(`top: ${top}, left: ${left}`);
  // debugger;
  this.classList.add("open");
}
.products {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  justify-content: center;
  min-width: 1000px;
  max-width: 1500px;
  margin-bottom: 300px;
}

.products .products__card {
  display: flex;
  flex-direction: column;
  width: 150px;
  height: 250px;
  margin-bottom: 30px;
  margin-right: 30px;
  margin-left: 30px;
  background-color: red;
  transform: scale(1);
  /* box-shadow: 3px 7px 55px -10px c(very-light); */
  transition: width 0.9s, height 0.9s, z-index 0.9s, top 6s, left 6s;
}

.products .products__card.card-1 {
  background-color: red;
}

.products .products__card.card-2 {
  background-color: blue;
}

.products .products__card.card-3 {
  background-color: green;
}

.products .products__card.card-4 {
  background-color: yellow;
}

.products .products__card.card-5 {
  background-color: pink;
}

.products .products__card.card-6 {
  background-color: gray;
}

.products .products__card.open {
  width: 550px;
  height: 800px;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  z-index: 120;
  box-shadow: 0 0 1000px 1000px c(box-overlay);
}
<div class="products">

  <div class="products__card card-1">

  </div>
  <div class="products__card card-2">

  </div>
  <div class="products__card card-3">

  </div>
  <div class="products__card card-4">

  </div>
  <div class="products__card card-5">

  </div>
  <div class="products__card card-6">

  </div>
</div>

在调试时有效:

上面提到的奇怪之处在于,当我在代码中插入调试器并手动跳过添加.open类的最后一步时,我在使用localhost的浏览器中的问题也得到了解决。如果您在jsfiddle或您自己的编辑器中遇到同样的问题,请尝试在debugger;之前添加this.classList.add("open");,然后打开控制台,然后单击该卡并在控制台中手动执行最后一步。您会注意到卡片从原来的位置扩展到需要6秒才能完成,这意味着在这种情况下应用了转换。

我的问题:

transitiontop的{​​{1}}仅适用于某些环境?这是一个浏览器问题?我正在使用最新的镀铬。有人知道更好的方法来获得相同的结果吗?

代码评论 - 显然,6秒不是我将在我的代码中使用的,它在这里使用只是为了使转换显而易见。

- 在我的源代码中,您可以看到,因为我无法从left转换为position static我必须使用Javascript将position fixed样式内联添加到元素之前添加了position fixed类,这样.open可以在添加transition时正常进行。

- 我还添加了.opentop内联值,以便在应用left样式时将卡保留在原始位置,因为您可能知道固定位置会将元素从其中移出流动,所以顶部和左侧保持原位。

- 我在css position: fixed类中添加了!important,因为没有它我不能覆盖你可能也知道的内联css。

谢谢

1 个答案:

答案 0 :(得分:1)

我刚刚通过应用一点黑客来解决我的问题。似乎在某些环境(localhost,jsfiddle)中,javascript引擎正在以比预期更快的速度添加.open类,并且在调试(慢速进程)时它工作正常的事实向我表明。所以我在最后一段代码中添加了一个setTimeout(),将它延迟了20个。这解决了我的问题,现在它在JSfiddle和我的计算机上工作正常。这是新编辑的样本:

https://jsfiddle.net/Lhr0d6cw/14/

setTimeout(() => {
    this.classList.add("open");
}, 20);

如果有人愿意分享,我还是想知道是否有更好的方法来制作这个动画!