【问题标题】:CSS simultaneous transition on multiple elementsCSS同时转换多个元素
【发布时间】:2021-02-10 23:47:05
【问题描述】:

所以,我有 3 个相同尺寸的 flexbox 容器。当我点击其中一个时,它应该会伸展得比其他的大,然后如果我再次点击它就会恢复正常。 我已经使用 JS 制作了它,并且可以正常工作。 问题是,当我已经拉伸了一个盒子并尝试拉伸另一个盒子时,过渡持续时间会增加。我不知道为什么。我认为不同的过渡会同时开始。

这是代码:

/* HTML */

<div class="flexbox">
            <div class="box-1" onclick="box1();">
                <h3>Box 1</h3>
                <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore</p>
            </div>
            <div class="box-2" onclick="box2();">
                <h3>Box 2</h3>
                <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore</p>
            </div>
            <div class="box-3" onclick="box3();">
                <h3>Box 3</h3>
                <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore</p>
            </div>
        </div>
/* CSS */

.flexbox {
    display: flex;
    width: auto;
    justify-content: center;
}

.flexbox div {
    border: 1px #ccc solid;
    border-radius: 10px;
    width: 250px;
    height: 250px;
    padding: 10px;
    margin: 2px 10px;
    transition: flex-grow 1s linear 0s;
}

.box-1{
  flex-grow: 0;
}

.box-2 {
  flex-grow: 0;
}

.box-3 {
  flex-grow: 0;
}
/* JS */

function box1(){
  const box1 = document.getElementsByClassName('box-1')[0];
  if(box1.style.flexGrow != '4'){
      box1.style.flexGrow = '4';
  } else {
    box1.style.flexGrow = '0';
  }

  const box2 = document.getElementsByClassName('box-2')[0];
  box2.style.flexGrow = '0';

  const box3 = document.getElementsByClassName('box-3')[0];
  box3.style.flexGrow = '0';
}

function box2(){
  const box2 = document.getElementsByClassName('box-2')[0];
  if(box2.style.flexGrow != '4'){
      box2.style.flexGrow = '4';
  } else {
    box2.style.flexGrow = '0';
  }

  const box1 = document.getElementsByClassName('box-1')[0];
  box1.style.flexGrow = '0';

  const box3 = document.getElementsByClassName('box-3')[0];
  box3.style.flexGrow = '0';
}

function box3(){
  const box3 = document.getElementsByClassName('box-3')[0];
  if(box3.style.flexGrow != '4'){
      box3.style.flexGrow = '4';
  } else {
    box3.style.flexGrow = '0';
  }

  const box1 = document.getElementsByClassName('box-1')[0];
  box1.style.flexGrow = '0';

  const box2 = document.getElementsByClassName('box-2')[0];
  box2.style.flexGrow = '0';
}

如何让转换持续时间始终相同(本例中为 1 秒)?

【问题讨论】:

  • 仅供参考,当您似乎在复制和粘贴代码并更改一些内容时,这通常暗示您应该尝试找出一种方法来制作一个函数,以便您可以重用它

标签: javascript html css flexbox


【解决方案1】:

可以对您的代码进行许多改进,以减少重复,避免与 getElementsByClassName 返回的实时 HTMLCollection 交互的复杂性,允许您避免使用内联 onclick 分配,并将使转换只需 1 秒。

下面的示例实现了单个grow() 函数,该函数由附加到每个框的侦听器调用。通过使用 .querySelectorAll('.box') 查询 DOM 并在每个元素上调用 addEventListener() 来迭代返回的 NodeList 来添加侦听器。

在 CSS 中,我们为我们希望盒子能够拥有的每个状态声明类 - 在本例中为 flex-grow: 0 和 flex-grow:4。然后在我们的grow() 函数中,我们只需根据单击的框根据需要添加或删除这些样式。

function grow(e){
      // if the clicked box already has class 'flexgrow4' return
      if (e.currentTarget.classList.contains('flexgrow4')) return;
      
      // otherwise find the element in the flexbox container that has
      // class 'flexgrow4' and replace it with 'flexgrow0'
      const lastActive = flexbox.querySelector('.flexgrow4');
      if (lastActive) lastActive.classList.replace('flexgrow4', 'flexgrow0');
      
      // finally, replace 'flexgrow0' with 'flexgrow4' on the clicked box
      e.currentTarget.classList.replace('flexgrow0', 'flexgrow4');
}

const flexbox = document.querySelector('.flexbox');
const boxes = document.querySelectorAll('.box')

boxes.forEach(box => box.addEventListener("click", grow, false));
.flexbox {
    display: flex;
    width: 100vw;
    justify-content: center;
}

.flexbox div {
    border: 1px #ccc solid;
    border-radius: 10px;
    width: 100px;
    height: 250px;
    padding: 10px;
    margin: 2px 10px;
    transition: all 1s linear 0s;
}

.flexgrow0 {
  flex-grow: 1;
}

.flexgrow4 {
  flex-grow: 4;
  background-color:tomato;
}
<div class="flexbox">
            <div class="box flexgrow0">
                <h3>Box 1</h3>
                <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore</p>
            </div>
            <div class="box flexgrow0">
                <h3>Box 2</h3>
                <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore</p>
            </div>
            <div class="box flexgrow0">
                <h3>Box 3</h3>
                <p>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore</p>
            </div>
        </div>

【讨论】:

  • 谢谢,这真的很有用。我真的处于起步阶段,所以我对这种语言并不放心。
  • 好的,我试过你的代码,但有两件事我不明白。首先,用于添加 eventListener 的代码在哪里运行?因为我已经把它放在我的 JS 文件中,但我不能自动工作。我怎样才能让它工作?其次,我认为当我“打开”第一个盒子时,与我已经“打开”一个盒子时相比,过渡的持续时间是不同的。
  • @AndreaMontanari 我已经研究了你提到的时间问题,第一次打开确实更快。这里有一个相关的问题:Transition flex-grow of items in a flexbox 讨论了过渡 flex-grow 的一些变幻莫测,但提出的解决方案并不能直接解决您的问题。一旦孩子们填满了父母的宽度,时间似乎就正确了,所以不要使用flex-grow: 0作为你的基本状态,你可以使用flex-grow: 1 - sn-p 已编辑。
  • 至于添加事件监听器,可以在DOM加载完成后在全局范围内运行,或者封装在一个函数中显式调用,但也一定要加上@987654337 @class 和每个孩子的相关起始班级 di
猜你喜欢
  • 2014-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多