为基于Flex Box的进度条设置动画时的异常故障

时间:2019-04-19 22:35:18

标签: javascript jquery html css flexbox

我正在尝试通过实现进度条来学习flexbox。 一切正常,直到我尝试使用jquery对事物进行动画处理。

enter image description here

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>

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

2 个答案:

答案 0 :(得分:3)

这是因为当您结合使用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>

答案 1 :(得分:2)

您可以通过切换元素上的类来尝试CSS动画:

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

.the-progress-bar {
    background-color: orangered;
}

.the-progress-bar-progress { 
    position: relative;
    width: 100%; height: 100%; 
    background-color: green;
    transition: transform 2s;
    transform: scaleX(0);
    transform-origin: 0 0;
}
.the-progress-bar-progress--25perc  { transform: scaleX(.25); }
.the-progress-bar-progress--50perc  { transform: scaleX(.5);  }
.the-progress-bar-progress--75perc  { transform: scaleX(.75); }
.the-progress-bar-progress--100perc { transform: scaleX(1);   }

您可以使用此示例函数来简单地更改应用于进度的类:

function changeProgress(e) {
    var progressBar = document.getElementById('the-progress-bar');
    progressBar.classList = 'b9k-progress';

    var targetClass = e.target.getAttribute('data-progressClass');
    if(targetClass && targetClass != '') { 
        progressBar.classList.add(targetClass);
    };
};

<button onclick='changeProgres();' data-progressClass="">ZERO</button>
<button onclick='changeProgres();' data-progressClass="the-progress-bar-progress--25perc">25%</button>
<button onclick='changeProgres();' data-progressClass="the-progress-bar-progress--50perc">50%</button>

function changeProgress(progressClass__string) {
    var targetClass = progressClass__string || '';
    document.getElementById('the-progress-bar').classList = 'b9k-progress ' + progressClass__string;
};

<button onclick="changeProgres();">ZERO</button>
<button onclick="changeProgres('the-progress-bar-progress--25perc');">25%</button>
<button onclick="changeProgres('the-progress-bar-progress--50perc');">50%</button>