Подтвердить что ты не робот

Могу ли я обнаружить, если начался произвольный переход CSS

В моей закрытой функции я хочу сделать все мое очищающее средство DOM после завершения css-переходов. Но не может быть никаких переходов, выполняемых/может быть многоступенчатым - (сохранение таблиц стилей из моих рук).

Как я могу написать функцию, например следующую

function close () {
  myEl.removeClass('open');
  if (animation is running/about to be run) {
    // wait for transition to end, then recursively check to see if another 
    // one has started, wait for that ...
    // then
    cleanUpDOM(); 
  } else {
    cleanUpDOM(); 
  }
}

Мои мысли до сих пор состоят в том, чтобы обернуть начальную проверку в timeout/requestAnimationFrame, чтобы дать анимации возможность начать, а затем проверить, не работает ли она. К сожалению, без события transitionstart я понятия не имею, как проверить, начался переход.

edit Ответы, рекомендующие jquery, неактуальны, поскольку анимация jquery - это анимация javascript, а не переходы CSS

4b9b3361

Ответ 1

О событиях переходаStart и transitionEnd:

Переход не может начаться нигде. Обычно переход начинается после некоторого события, когда вы меняете состояние элемента DOM, меняя стили по классам или чему-то еще. Поэтому вы знаете, когда переход начинается, потому что вы запускаете его в своем коде.

Во время перехода пользовательский ввод-вывод не блокирует, поэтому переход является асинхронным, а затем переход закончится, вы не знаете правильно. Поэтому вам нужно transitionEnd событие, чтобы что-то сделать, а затем переход закончился в javascript.

О событии переходаEnd: Просто посмотрите jsfiddle

Ответ 2

Здесь мое решение до сих пор - немного взломанно и работает только тогда, когда какой-либо элемент может перейти, и не работает с transition-property: all... но это многообещающий старт

function toCamelStyleProp (str) {
    return str.replace(/(?:\-)([a-z])/gi, function ($0, $1) {
        return $1.toUpperCase();
    });
}

function toHyphenatedStyleProp (str) {
    return str.replace(/([A-Z])/g, function (str,m1) {
        return '-' + m1.toLowerCase();
    }).replace(/^ms-/,'-ms-');
}

function getPrefixedStyleProp (prop) {
    prop = toCamelStyleProp(prop);
    prop = Modernizr.prefixed(prop);
    return toHyphenatedStyleProp(prop);
}

function getStyleProperty (el, prop) {
    return getComputedStyle(el,null).getPropertyValue(getPrefixedStyleProp(prop));
}

function doAfterTransition ($wrapper, cssClass, mode, $transitioningEl, callback) {
    $transitioningEl = $transitioningEl || $wrapper;

    var transitioningEl = $transitioningEl[0],
        duration = +getStyleProperty(transitioningEl, 'transition-duration').replace(/[^\.\d]/g, ''),
        transitioners = getStyleProperty(transitioningEl, 'transition-property').split(' '),
        initialState = [],
        changedState = [],
        i,
        callbackHasRun = false,

        //makes sure callback doesn't get called twice by accident
        singletonCallback = function () {
            if (!callbackHasRun) {
                callbackHasRun = true;
                callback();
            }
        };

    // if no transition defined just call the callback
    if (duration === 0) {
        $wrapper[mode + 'Class'](cssClass);
        callback();
        return;
    }

    for (i = transitioners.length - 1;i>=0;i--) {
        initialState.unshift(getStyleProperty(transitioningEl, transitioners[i]));
    }

    $wrapper[mode + 'Class'](cssClass);

    setTimeout(function () {
        for (i = transitioners.length - 1;i>=0;i--) {
            changedState.unshift(getStyleProperty(transitioningEl, transitioners[i]));
        }

        for (i = transitioners.length - 1;i>=0;i--) {
            if (changedState[i] !== initialState[i]) {
                $transitioningEl.transitionEnd(singletonCallback);

                // failsafe in case the transitionEnd event doesn't fire
                setTimeout(singletonCallback, duration * 1000);
                return;
            }
        }
        singletonCallback();
    }, 20);
}

Ответ 3

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

Однако, если вы можете перейти от перехода к анимации ключевых фреймов, тогда у вас будет необходимое событие - animationStart и animationEnd, и тогда будет легко выяснить, есть ли анимация.

Ответ 5

Вот функция, которая ожидает, что страница Html станет стабильной. т.е. когда все анимации закончены. В приведенном ниже примере он ожидает, что Html останется неизменным в течение 200 миллисекунд и максимальный тайм-аут в 2 секунды.

Вызвать функцию с помощью...

waitUntilHtmlStable(yourCallback, 200, 2000);

Функция...

waitUntilHtmlStable = function (callback, unchangedDuration, timeout, unchangedElapsed, html) {
    var sleep = 50;
    window.setTimeout(function () {
        var newHtml = document.documentElement.innerHTML;
        if (html != newHtml) unchangedElapsed = 0;
        if (unchangedElapsed < unchangedDuration && timeout > 0)
            waitUntilHtmlStable(callback, unchangedDuration, timeout - interval, unchangedElapsed + interval, newHtml);
        else
            callback();
    }, sleep);
};

В моем случае я хотел быть уверенным в новых элементах, где они присутствуют. Если вы хотите отслеживать движение анимации, измените document.documentElement.innerHTML на

JSON.stringify(Array.prototype.slice.call(document.documentElement.getElementsByTagName("*"), 0)
.map(function(e) {
        var x = e;
        var r = x.getBoundingClientRect();
        while (r.width == 0 || r.height == 0) {
            x = x.parentNode;
            r = x.getBoundingClientRect();
        }
        return r;
    }));

Ответ 7

Если вы планируете сделать переход css, вы можете проверить плагин jQuery Transit http://ricostacruz.com/jquery.transit/

Очень мощный и полезный, вы можете получить значение преобразования x. css ('x'), например.

Ответ 9

вы можете использовать Jquery, что было бы намного проще, например, вы могли бы использовать .animate, подобный этому

(function(){
            var box = $('div.box')
            $('button').on('click', function(){
                box.animate({ 'font-size' : '40px'})
                .animate({'color': 'red'});
            })
        })();

или просто выполните функцию обратного вызова