当我点击按钮时,会出现一个滑块。 (here is an example of what it looks like,不注意此代码)
滑块通过动画显示。动画结束后,我应该包含一个我从服务器加载的HTML页面。我需要在之后的滑块中应用HTML 动画,否则动画会停止(重新计算DOM)。
等待数据准备好和转换完成
为什么?如果我在动画期间应用HTML,它会在将新HTML添加到DOM时停止动画。所以我等到第4步之前结束。
这是缩短的代码:
// Start loading data & animate transition
var count = 0;
var data = null;
++count;
$.get(url, function (res) {
data = res;
cbSlider();
});
// Animation starts here
++count;
$(document).on('transitionend', '#' + sliderId, function () {
$(document).off('transitionend', '#' + sliderId);
cbSlider()
});
function cbSlider() {
--count;
// This condition is only correct when both GET request and animation are finished
if (count == 0) {
// Attempt to enforce the frame to finish (doesn't work)
window.requestAnimationFrame(() => { return });
$('#' + sliderId + ' .slider-content').html(data);
}
}
transitionend
过早被召唤。它使最后一个动画帧过长(477.2ms),最后一帧未在transitionend
事件中呈现。
从Google文档中,我可以告诉您Pixel Pipeline的“绘制和合成”步骤在<{strong> Event(transitionend)
之后被称为:
也许我在想这个。
我该如何处理这种动画?
如何等待动画完全渲染和渲染?
答案 0 :(得分:2)
我不确定为什么transitionend
在最后一帧渲染之前被触发,但在这个(非常粗略的)测试中,似乎setTimeout
确实有帮助。 ..
第一个例子显示了如何过早地进行html计算和注入。第二个示例将长时间运行的方法包装在setTimeout
中,并且似乎不会触发动画中的任何中断。
var ended = 0;
var cb = function() {
ended += 1;
if (ended == 2) {
$(".animated").html(createLongHTMLString());
}
}
$(".load").click(function() {
$(".animated").addClass("loading");
$(".animated").on("transitionend", cb);
setTimeout(cb, 100);
});
function createLongHTMLString() {
var str = "";
for (var i = 0; i < 100000; i += 1) {
str += "<em>Test </em>";
}
return str;
};
.animated,
.target {
width: 100px;
height: 100px;
position: absolute;
text-align: center;
line-height: 100px;
overflow: hidden;
}
.target,
.animated.loading {
transform: translateX(300%);
}
.animated {
background: green;
z-index: 1;
transition: transform .2s linear;
}
.target {
background: red;
z-index: 0;
}
.wrapper {
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="animated">Loading</div>
<div class="target"></div>
</div>
<button class="load">load</button>
setTimeout
似乎解决了它在html注入代码周围加setTimeout
。
var ended = 0;
var cb = function() {
ended += 1;
if (ended == 2) {
setTimeout(function() {
$(".animated").html(createLongHTMLString());
});
}
}
$(".load").click(function() {
$(".animated").addClass("loading");
$(".animated").on("transitionend", cb);
setTimeout(cb, 100);
});
function createLongHTMLString() {
var str = "";
for (var i = 0; i < 100000; i += 1) {
str += "<em>Test </em>";
}
return str;
};
.animated,
.target {
width: 100px;
height: 100px;
position: absolute;
text-align: center;
line-height: 100px;
overflow: hidden;
}
.target,
.animated.loading {
transform: translateX(300%);
}
.animated {
background: green;
z-index: 1;
transition: transform .2s linear;
}
.target {
background: red;
z-index: 0;
}
.wrapper {
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="animated">Loading</div>
<div class="target"></div>
</div>
<button class="load">load</button>
答案 1 :(得分:0)
好吧,如果转换不按照你想要的方式为你工作,你可以回过头几年并使用jQuery动画代替吗?
(function(slider){
$.get(url, function (res) {
slider.animate({
// put whatever animations you need here
left: "5%",
}, 5000, function() {
// Animation complete.
slider.find('.slider-content').html(res);
});
});
}($('#' + sliderId)));
您也可以同时启动这两个操作,然后仅在动画完成并且请求完成后才将html添加到文档中,但这需要一个标记。
(function(slider){
// whether the animation is finished
var finished = false;
// whether the html has been added already
var added = false;
// your html data
var html = null;
function add() {
if (finished && html && !added) {
// make sure function will only add html once
added = true;
slider.find('.slider-content').html(html);
}
}
$.get(url, function (res) {
html = res;
add();
});
slider.animate({
// put whatever animations you need here
left: "5%",
}, 5000, function() {
// Animation complete.
finished = true;
add();
});
}($('#' + sliderId)));