Причудливый сбой при анимации индикатора выполнения на основе flex box - PullRequest
3 голосов
/ 20 апреля 2019

Я пытаюсь изучить 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 ]

3 голосов
/ 20 апреля 2019

Это потому, что когда вы используете CSS flexbox в сочетании с шириной в процентах, вы заставляете браузер делать несколько проходов при попытке определить окончательную ширину элемента. Это приводит к тому, что полоса изначально превышает свою ширину до> 100%, прежде чем jQuery правильно анимирует ее до целевого значения.

Решение 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>
2 голосов
/ 20 апреля 2019

Вы можете попробовать это с 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...