首页 > 解决方案 > 为基于 flex 框的进度条设置动画时出现一个奇怪的故障

问题描述

我正在尝试通过实现进度条来学习 flexbox。一切正常,直到我尝试用 jquery 为它制作动画......

在此处输入图像描述

Animate将宽度设置为至少 75% 后,右半部分似乎效果不佳。

就像绿色条设置为非常大的宽度一样,因为它实际上需要大约一秒钟才能从 100%+ 恢复。

我不确定原因是我不太了解 flexbox 还是 jQuery 出于某种原因吓坏了……

这是一个已知的问题?我做错什么了吗?这是我页面的代码。

这是我的代码:

button {
  height: 50px;
  margin: 10px;
  width: 50px;
}

.b9k-progress {
  border: solid black 2px;
  flex-direction: row;
  display: flex;
  height: 50px;
  margin: 10px;
  padding: 5px;
}

.b9k-left,
.b9k-right {
  height: inherit;
  padding: 0;
  margin: 0;
}

.b9k-left {
  background-color: green;
  opacity: 1;
}

.b9k-right {
  background: orangered;
  flex-grow: 1;
}
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>

<div style="width: 80%;margin: 20px 10% ;">
  <button onclick='$("#the-progress-bar>.b9k-left").animate({"width": "0"},2000);'>ZERO</button>
  <button onclick='$("#the-progress-bar>.b9k-left").animate({"width": "20%"},2000);'>25%
    </button>
  <button onclick='$("#the-progress-bar>.b9k-left").animate({"width": "50%"},2000);'>50%
    </button>
  <button onclick='$("#the-progress-bar>.b9k-left").animate({"width": "75%"},2000);'>75%
    </button>
  <button onclick='$("#the-progress-bar>.b9k-left").animate({"width": "100%"},2000);'>100%
    </button>
</div>


<div id="the-progress-bar" class="b9k-progress">
  <div class="b9k-left"></div>
  <div class="b9k-right"></div>
</div>

这是一个已知的问题?我做错什么了吗?

标签: javascriptjqueryhtmlcssflexbox

解决方案


这是因为当您将 CSS flexbox与基于百分比的宽度结合使用时,您会迫使浏览器在尝试确定元素的最终宽度时进行多次传递。在 jQuery 正确地将其设置为目标值之前,这会导致栏最初超出其宽度至 >100%。

解决方案 1:使用 CSS 过渡

您甚至根本不需要使用 jQuery 的动画功能。使用起来可能很麻烦,并且具有人们不知道.stop(true, true)的全部内容(例如用于清除队列,而您没有使用)。您想要实现的目标可以完全使用 CSS 转换来完成:

$(function() {
  $('.button').on('click', function() {
    $('#the-progress-bar > .b9k-left').width($(this).data('target-width'));
  });
});
button {
  height: 50px;
  margin: 10px;
  width: 50px;
}

.b9k-progress {
  border: solid black 2px;
  flex-direction: row;
  display: flex;
  height: 50px;
  margin: 10px;
  padding: 5px;
}

.b9k-left,
.b9k-right {
  height: inherit;
  padding: 0;
  margin: 0;
  
  /* Enable transition of width */
  transition: width 2s ease-in-out;
}

.b9k-left {
  background-color: green;
  opacity: 1;
  
  /* Give the width a starting value */
  width: 0;
}

.b9k-right {
  background: orangered;
  flex-grow: 1;
}
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>

<div style="width: 80%;margin: 20px 10% ;">
  <button class="button" data-target-width="0">ZERO</button>
  <button class="button" data-target-width="25%">25%
    </button>
  <button class="button" data-target-width="50%">50%
    </button>
  <button class="button" data-target-width="75%">75%
    </button>
  <button class="button" data-target-width="100%">100%
    </button>
</div>


<div id="the-progress-bar" class="b9k-progress">
  <div class="b9k-left"></div>
  <div class="b9k-right"></div>
</div>

解决方案 2:不要使用 flexbox

解决这个问题的一种方法是实际上只是删除 CSS flexbox 的使用,而是将橙色背景分配给父元素:

button {
  height: 50px;
  margin: 10px;
  width: 50px;
}

.b9k-progress {
  background-color: orangered;
  border: solid black 2px;
  box-shadow: inset 0 0 0 5px white;
  height: 50px;
  margin: 10px;
  padding: 5px;
}

.b9k-left {
  height: inherit;
  padding: 0;
  margin: 0;
}

.b9k-left {
  background-color: green;
  opacity: 1;
}
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>

<div style="width: 80%;margin: 20px 10% ;">
  <button onclick='$("#the-progress-bar>.b9k-left").animate({"width": "0"},2000);'>ZERO</button>
  <button onclick='$("#the-progress-bar>.b9k-left").animate({"width": "20%"},2000);'>25%
    </button>
  <button onclick='$("#the-progress-bar>.b9k-left").animate({"width": "50%"},2000);'>50%
    </button>
  <button onclick='$("#the-progress-bar>.b9k-left").animate({"width": "75%"},2000);'>75%
    </button>
  <button onclick='$("#the-progress-bar>.b9k-left").animate({"width": "100%"},2000);'>100%
    </button>
</div>


<div id="the-progress-bar" class="b9k-progress">
  <div class="b9k-left"></div>
</div>


推荐阅读