首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >事件“transitionend”调用得太早,延迟了呈现

事件“transitionend”调用得太早,延迟了呈现
EN

Stack Overflow用户
提问于 2016-08-26 13:05:13
回答 2查看 1.9K关注 0票数 14

我在做什么,怎么了

当我点击一个按钮时,会出现一个滑块。(下面是一个例子,说明它是什么样子不注意此代码)

滑块通过动画显示。动画完成后,我应该包含从服务器加载的HTML页面。我需要在动画之后在滑块中应用,否则动画就停止了( DOM被重新计算)。

我的算法

  1. 启动请求以获取要在滑块中显示的HTML
  2. 启动动画
  3. 等待数据就绪,将完成转换 为什么?如果我在动画期间应用HTML,它将停止动画,同时将新的HTML添加到DOM中。因此,我在第4步之前等待这两种情况的结束。
  4. 在滑块内应用HTML

以下是缩短的代码:

代码语言:javascript
复制
// 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文档中,我可以告诉您,像素流水线的画图和复合步骤名为,名为 Event(transitionend)

也许我想得太多了。

我该如何处理这种动画呢?

我如何等待动画完全完成和渲染?

EN

回答 2

Stack Overflow用户

发布于 2016-09-01 15:47:58

我不知道为什么在最后一个框架呈现之前就会触发transitionend,但是在这个(非常粗糙的)测试中,setTimeout似乎确实有帮助……

第一个例子展示了html计算和注入是如何过早发生的。第二个示例将长时间运行的方法封装在setTimeout中,在动画中似乎不会触发任何插入。

示例1:问题的再现

代码语言:javascript
复制
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;
};
代码语言:javascript
复制
.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;
}
代码语言:javascript
复制
<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>

示例2:在其中,setTimeout似乎修复了它

在html注入代码周围使用setTimeout

代码语言:javascript
复制
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;
};
代码语言:javascript
复制
.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;
}
代码语言:javascript
复制
<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>

票数 2
EN

Stack Overflow用户

发布于 2016-08-29 09:10:43

好吧,如果转换没有按照您想要的方式工作,那么您可以追溯几年前使用jQuery动画吗?

代码语言:javascript
复制
(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添加到文档中,但这需要一个标志。

代码语言:javascript
复制
(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)));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39167044

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档