是否有一种方法来检测css转换已经中止/中断

Is there a way to detect that a css transition has been aborted/interruted?

本文关键字:转换 css 中断 检测 方法 一种 是否      更新时间:2023-09-26

根据mdn transitionend文档,如果css的transition-property被移除,或者元素(或者它的父元素之一)变成display:none,那么transition的transitionend事件将不会被触发。

我想知道是否有任何方法来检测这样的情况从javascript方面(即。:过渡已中断)。就我所见,没有过渡中断事件或过渡中止事件,但也许我错过了什么?

你知道吗?

我试着对它做了一点研究,除了transitionend之外真的没有其他的过渡事件,但我发现这支笔试图使用transitionend事件来模拟transitionstart事件,该事件在很短的延迟后触发。

基于该技术,我尝试模拟transitioncancel事件并获得了一些"不错"的结果。下面是一个小演示代码(后面是解释):

<h1>Hello World</h1>
CSS

h1 {
    margin-left: 0;
    opacity: 0.99999;
    transition: margin-left 1s ease, opacity 0.0001ms ease;
}
h1:hover {
    opacity: 1;
    margin-left: 500px;
}
Javascript

var h1 = document.querySelector('h1');
var styles = getComputedStyle(h1);
var duration = resolveDuration(styles.transitionProperty,
    styles.transitionDuration);
var timer = null;
h1.addEventListener('transitionend', function(e) {
    if (e.propertyName === 'opacity') {
        timer = setTimeout(function() {
            console.log('transition cancelled!');
        }, duration);
    } else {
        clearTimeout(timer);
    }
});
function resolveDuration(property, duration) {
    var properties = property.split(/,'s+/g);
    var durations = duration.split(/,'s+/g);
    for (var i = 0; i < properties.length; i++) {
        if (properties[i] !== 'opacity') {
            var unit = durations[i].replace(/'d+'.?'d*/, '');
            var value = parseInt(durations[i].replace(unit, ''));
            if (unit === 's') {
                return value * 1000;
            }
            return value;
        }
    }
    return 0;
}

  • 基本上,这是在模拟的transitionstart之后启动setTimeout调用,持续时间设置为transition-duration(在resolveDuration函数中标准化为毫秒)。

  • 当传递给setTimeout的函数被执行时,表示转换被取消

  • 当另一个transitionend事件被发出,而不是opacity属性(用于伪造transitionstart)时,setTimeout调用被取消,因此伪造的transitioncancel不会被发出。

此解决方案的问题

  • 需要另一个过渡属性(在本例中为opacity)来代替transitionstart

  • 只能处理一个过渡属性

  • transitioncancel只在transition-duration之后触发,而不是在转换被取消时立即触发。

查看这个小提琴的演示