首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有多个转换的transitionEnd事件,检测最后一个转换

具有多个转换的transitionEnd事件,检测最后一个转换
EN

Stack Overflow用户
提问于 2016-11-10 23:15:57
回答 4查看 3.6K关注 0票数 9

事件在结束的转换上激发

首先

而不是最后,这不是我们想要的行为。有什么解决方法吗?

代码语言:javascript
复制
document.querySelector('a').addEventListener('transitionend', function(){
  var time = (new Date().getMinutes()) + ':' + (new Date().getSeconds());
  console.log('transitionEnd - ', time);
});
代码语言:javascript
复制
a{
  display:block;
  opacity:.5;
  width:100px;
  height:50px;
  background:lightblue;
}
a:hover{
  width:200px;
  height:100px;
  background:red;
  transition: 4s width,     /* <-- "transitionEnd" should fire after this */
              2s height,
              .5s background;  
}
代码语言:javascript
复制
Hover me

现在我检查了Chrome (我不使用那个浏览器),我看到该事件被调用了3次,每个转换一个。无论如何,我需要它在最后一个,在Firefox中触发。(我不知道元素上有多少个转换,想知道哪个是最后一个)

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-05-26 23:18:26

返回一个名为

在事件对象中。

来源

因此,您可以测试所需的属性,并使用简单的逻辑来过滤回调:

代码语言:javascript
复制
document.querySelector('a').addEventListener('transitionend', function(event){
    if(event.propertyName !== 'width') return;
    console.log('transitionEnd - width!');
});
票数 6
EN

Stack Overflow用户

发布于 2016-11-11 02:31:38

一个有点老生常谈的解决方案可能是试图找出哪个css属性具有最长的总持续时间。您可以使用

在您的

元素,并将所有

属性。

您可以在触发三次的常规事件处理程序中做到这一点(它非常快),或者创建一个函数来预先计算您正在寻找的属性名称。

这种方法的主要问题是:

Css允许您使用

在一条语句中,你可能需要做更多的计算。

当您要更改计算样式时,可能很难预测计算的样式是什么。

样式悬停时,或在过渡之前/之后添加新类时。

代码语言:javascript
复制
var getValues = function(str) {
  return str
    .replace(/[A-Z]/gi, "")
    .split(", ")
    .map(parseFloat);
};

var getMaxTransitionProp = function(el) {
  var style = window.getComputedStyle(el);
  var props = style.transitionProperty.split(", ");

  var delays = getValues(style.transitionDelay);
  var durations = getValues(style.transitionDuration);
  var totals = durations.map(function(v, i) {
    return v + delays[i];
  });

  var maxIndex = totals.reduce(function(res, cur, i) {
    if (res.val > cur) {
      res.val = cur;
      res.i = i;
    }
    return res;
  }, {
    val: -Infinity,
    i: 0
  }).i;

  return props[maxIndex];
}

var lastEventListenerFor = function(el, cb) {
  var lastProp = getMaxTransitionProp(el);
  return function(e) {
    if (e.propertyName == lastProp) {
      cb(e);
    }
  };
}

var a = document.querySelector("a");
var cb = function(e) {
  console.log("End");
};

a.addEventListener("transitionend", lastEventListenerFor(a, cb));
代码语言:javascript
复制
a {
  display: block;
  opacity: .5;
  width: 100px;
  height: 50px;
  background: lightblue;
  transition: 3s width,
  /* <-- "transitionEnd" should fire after this */
  2s height, .5s background;
}
a:hover {
  width: 200px;
  height: 100px;
  background: red;
}
代码语言:javascript
复制
Hover me

票数 2
EN

Stack Overflow用户

发布于 2017-04-19 22:31:40

我现在可能是老问题了,但遇到了同样的麻烦。以这种方式解决:

代码语言:javascript
复制
document.querySelector('a').addEventListener('click', function(e){
  this.classList.toggle('animate');
  let style = window.getComputedStyle(this, null);
  Promise.all(style.transition.split(',').map((prop) => {
     prop = prop.trim().split(/\s+/);
     return Promise.race([
         new Promise((resolve) => {
              let h = (e) => {
                   if (e.propertyName == prop[0])
                        resolve('transitionEnd ' + prop[0]);
              };
              this.addEventListener('transitionend', h, {once:false});
         }),
         new Promise((resolve) => 
              setTimeout(
                  () => resolve('TIMEOUT ' + prop[0]),
                  prop[1].replace(/s/,'')*1000 + 100
              )
         )
     ])
  }))
  .then((res) => {
     console.log(res + 'DONE!!!!');
     /*  do your stuff */
  });
});

解释:

首先,我们确定哪些属性实际上应该更改,然后拆分/映射/转换它以执行操作。通常它的格式如下:

“宽4s缓0,高2s缓0,..”

接下来我们使用Promise.race,因为并不总是触发transitionEnd (属性对于两个状态是相同的,或者属性名称在规则和事件中不匹配(背景可以是背景色),等等),我们需要tp回退到简单的超时

最后,我们等待每个属性的所有timeout/eventListeners

免责声明:

这是一个例子,我承认它使用了很多

魔法

,并且错过了很多检查

即使动画被取消,"callback“也会被触发(超时也会被触发)

需要ES6 :)

你可以玩它

jsfiddle

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40530990

复制
相关文章

相似问题

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