2015-11-16 2 views
1

Я хочу создать панель обработки, которая выполняет функцию foo(), когда она вырастет до 100% ширины.Панель обработки с остановкой при наведении

HTML:

<div></div> 

CSS:

position: absolute; 
top: 0px; 
left: 0px; 
height: 2px; 
width: 0px; 
background-color: rgba(0, 0, 0, 0.3); 

Так что я попробовал сделать это с помощью CSS анимации.

JS:

var duration = parseInt("15"); 
var bar = $("[...] div"); 
doSomething = (function() { 
    bar.css({ 
     "animation-duration" : duration+"s", 
     "animation-name" : "expand", 
     "animation-timing-function" : "linear" 
    }); 
    bar.on("animationend oAnimationEnd MSAnimationEnd mozAnimationEnd webkitAnimationEnd", function(e) { 
     bar.css("animation-name", "none"); 
     foo(); 
     $(this).off(e); 
    }); 
    doSomething(); 
}); 

Это отлично работает в первом запуске, но это не цикл.

Но с этим решением я могу добавить остановку в hover легко с:

CSS:

animation-play-state: paused; 

Я попробовал решение с JQuery animate(), работ цикла, но я не знаю, как добавьте остановку при наведении и приостановите анимацию, потому что в jQuery нет возможности сделать что-то подобное. Конечно, я могу остановить анимацию, но когда я запускаю ее снова, она воспроизводит остальную часть ширины с одинаковой продолжительностью.

JS:

doSomething = (function() { 
    /* First try 
    interval = setInterval(function(){ 
     bar.animate({ 
      width: "100%", 
     }, duration, "linear", function() { 
      bar.css("width", "0px"); 
      foo(); 
     }); 
    }, 0);*/ 
    bar.animate({ 
     width: "100%", 
    }, duration, "linear", function() { 
     bar.css("width", "0px"); 
     foo(); 
    }); 
}); 
$("[parent of bar]") 
    .mouseenter(function() { 
     bar.stop(); 
    }) 
    .mouseleave(function() { 
     bar.finish(); /* Animate: 100% - currentWidth in duration */ 
    }); 

Поэтому любые другие идеи?

+0

Возможно, демонстрация поможет, но с помощью CSS-решения вам придется повторно присоединить анимацию через определенный промежуток времени (например, тайм-аут или задержка) или после выполнения «foo()» для нее перезапуск. В противном случае анимация не будет выполнена из-за параметра «анимация-имя: нет». – Harry

ответ

1

В вашем коде вы обнуляете или удаляете анимацию при запуске события animationend. В связи с этим цикл не будет работать. Если вы хотите поддерживать цикл, вы можете либо вызвать doSomething в конце обработки функции foo(), чтобы повторно подключить анимацию и обработчик событий.

В приведенном ниже фрагменте функция foo() отобразит текст «Анимация завершена ..» после завершения анимации, а затем после 2-секундной перезагрузки анимации.

var duration = parseInt("15"); 
 
var bar = $("div.animated-element"); 
 
doSomething = (function() { 
 
    bar.css({ 
 
    "animation-duration": duration + "s", 
 
    "animation-name": "expand", 
 
    "animation-timing-function": "linear" 
 
    }); 
 
    bar.on("animationend oAnimationEnd MSAnimationEnd mozAnimationEnd webkitAnimationEnd", function(e) { 
 
    bar.css("animation-name", "none"); 
 
    foo(); 
 
    $(this).off(e); 
 
    }); 
 
}); 
 
doSomething(); 
 

 
function foo() { 
 
    var op = $('div.output'); 
 
    op.html("Animation Completed...."); 
 
    window.setTimeout(function() { 
 
    doSomething(); 
 
    op.html(""); 
 
    }, 2000); 
 
}
div.animated-element { 
 
    position: absolute; 
 
    top: 0px; 
 
    left: 0px; 
 
    height: 50px; 
 
    width: 0px; 
 
    background-color: rgba(0, 0, 0, 0.3); 
 
} 
 
@keyframes expand { 
 
    from { 
 
    width: 0px; 
 
    } 
 
    to { 
 
    width: 200px; 
 
    } 
 
} 
 
div.animated-element:hover { 
 
    animation-play-state: paused !important; /* important is needed because of inline animation styles or you can set this also inline using jQuery*/ 
 
} 
 

 
div.output{ 
 
    margin-top: 50px; 
 
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> 
 
<div class='animated-element'></div> 
 
<div class='output'></div>


Или, вы можете также animationiteration событие, чтобы запустить функцию foo() в конце каждой итерации анимации и использовать animationend огонь foo() когда анимация завершается один раз и для всех.

В приведенном ниже фрагменте функция foo() отобразит текст «Анимация завершена ..» (вводящий в заблуждение текст, но вы получите текст) после каждой итерации анимации, после задержки за 2 секунды текст исчезнет, ​​но анимация будет продолжать работать до тех пор, пока не завершится его 5 итераций. Наконец, после 5 итераций анимация будет остановлена.

var duration = parseInt("15"); 
 
var bar = $("div.animated-element"); 
 
doSomething = (function() { 
 
    bar.css({ 
 
    "animation-duration": duration + "s", 
 
    "animation-name": "expand", 
 
    "animation-timing-function": "linear", 
 
    "animation-iteration-count" : "5" 
 
    }); 
 
    bar.on("animationend oAnimationEnd MSAnimationEnd mozAnimationEnd webkitAnimationEnd", function(e) { 
 
    bar.css("animation-name", "none"); 
 
    foo(); 
 
    $(this).off(e); 
 
    }); 
 
    bar.on("animationiteration oAnimationIteration MSAnimationIteration mozAnimationIteration webkitAnimationIteration", function(e) { 
 
    foo(); 
 
    }); 
 
}); 
 
doSomething(); 
 

 
function foo() { 
 
    var op = $('div.output'); 
 
    op.html("Animation Completed...."); 
 
    window.setTimeout(function() { 
 
    op.html(""); 
 
    }, 2000); 
 
}
div.animated-element { 
 
    position: absolute; 
 
    top: 0px; 
 
    left: 0px; 
 
    height: 50px; 
 
    width: 0px; 
 
    background-color: rgba(0, 0, 0, 0.3); 
 
} 
 
@keyframes expand { 
 
    from { 
 
    width: 0px; 
 
    } 
 
    to { 
 
    width: 200px; 
 
    } 
 
} 
 
div.animated-element:hover { 
 
    animation-play-state: paused !important; /* important is needed because of inline animation styles or you can set this also inline using jQuery*/ 
 
} 
 

 
div.output{ 
 
    margin-top: 50px; 
 
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> 
 
<div class='animated-element'></div> 
 
<div class='output'></div>

Вы можете прочитать больше о различных связанных анимационных событий в spec here.

+1

Спасибо, чувак, тайм-аут был недостающим! Я не знаю, почему javascript не зацикливается без тайм-аута, но эй он работает :) – Coli

+0

@Coli: С удовольствием узнаем, что это помогло :) Когда вы не используете таймаут, свойства удаляются (через 'animation-name: none') и добавлен (через 'foo()') сразу, и поэтому возможно, что UA не видит изменений. Поскольку он не видит никаких изменений, он предположил бы, что одна итерация анимации уже завершена и ничего не делает. Когда мы добавляем тайм-аут, между удалением анимации и ее повторным добавлением происходит временной интервал, который заставляет браузер забыть старое состояние. – Harry

2

$(document).ready(function() { 
 
      $('.childSpan').addClass('progress'); 
 
      $('.childSpan').on('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() { 
 
       console.log('100%');//call the foo() function here 
 
       $('.childSpan').removeClass('progress'); 
 
       setTimeout(function() { 
 
        $('.childSpan').addClass('progress'); 
 
       }, 1); 
 
      }); 
 
     });
@-webkit-keyframes progress { 
 
    0%{width:0%;} 
 
    50%{width:50%;} 
 
    100%{width:100%;} \t 
 
} 
 

 
@-moz-keyframes progress { 
 
    0%{width:0%;} 
 
    50%{width:50%;} 
 
    100%{width:100%;} \t 
 
} 
 

 
@-o-keyframes progress { 
 
    0%{width:0%;} 
 
    50%{width:50%;} 
 
    100%{width:100%;} \t 
 

 
} 
 

 
@keyframes progress { 
 
    0%{width:0%;} 
 
    50%{width:50%;} 
 
    100%{width:100%;} \t 
 

 
} 
 
.progress { 
 
    -webkit-animation-name: progress; 
 
    -moz-animation-name: progress; 
 
    -o-animation-name: progress; 
 
    animation-name: progress; 
 
    -webkit-animation: progress 2s linear; 
 
    -moz-animation: progress 2s linear; 
 
    -o-animation: progress 2s linear; 
 
    -ms-animation: progress 2s linear; 
 

 
} 
 

 
.parentDiv:hover > .childSpan { 
 
    -webkit-animation-play-state: paused; 
 
    animation-play-state: paused; 
 
} 
 
.parentDiv{width:300px;background:black;height:50px;} 
 
.childSpan{background: red none repeat scroll 0 0;display: block;height: 50px;width:0%;}
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script> 
 
<div id="processDiv" class="parentDiv"> 
 
<span id="process" class="childSpan"> 
 
\t 
 
</span> 
 
</div>

Просто попробуйте это, только нужно добавить и удалить класс после завершения анимации.

В случае, если вам не нужно событие после завершения, то остальное можно сделать с помощью CSS только нужно изменить тип анимации для

-webkit-animation: shake 2s infinite linear; 
-moz-animation: shake 2s infinite linear; 
-o-animation: shake 2s infinite linear; 
-ms-animation: shake 2s infinite linear; 

и по умолчанию добавить класс прогресса на пролете, нет нужен любой код jquery для этого случая.

+0

По сути то же самое. Единственное различие заключается в том, что вы добавляете/удаляете класс, тогда как мой ответ заключается в добавлении/удалении свойств. Мне просто интересно, пытается ли OP установить разные «анимационные длительности» в их фактическом коде (в зависимости от того, как они используют переменную и 'parseInt'). Если это так, то добавление/удаление класса будет очень жестким, так как вам придется редактировать правила CSS. – Harry

+0

Чтобы сделать динамическую продолжительность, нам нужно добавить css (относящуюся к анимации) через jquery с переменной продолжительностью анимации, как это сделано в исходном коде для элемента bar elemnt. –

+0

Это именно то, что я говорил (и использовал в своем ответе). Я вообще не отказываюсь от вашего ответа, просто говоря, что класс add/remove может быть или не быть самым легким подходом в зависимости от того, что хочет OP. – Harry

Смежные вопросы