Да, есть способ. Далее следует демонстрация, объяснение ниже. Есть несколько очень важных предостережений, так что обязательно прочитайте.
Следующий код проверяет, может ли браузер выполнять анимацию между двумя значениями.
Код
демонстрация jsFiddle.
/*
@param property The property to test.
@param from A valid starting value for the animation.
@param to A valid ending value for the animation.
@param [element] The element to test with. (Required for testing
properties with prerequisites, e.g. "top" requires
non-static position.)
*/
function isAnimationSupported(property, from, to, element) {
var doc = document.documentElement,
style = doc.appendChild(document.createElement("style")),
rule = [
'capTest{',
'0%{', property, ':', from, '}',
'100%{', property, ':', to, '}',
'}'
].join(''),
propCamel = property.toCamelCase(),
prefixes = 'moz ms o webkit '.split(' '), // Unprefixed last, see comments.
prefixCount = prefixes.length,
canAnimate = false;
element = doc.appendChild((element)
? element.cloneNode(false)
: document.createElement('div'));
// Detect invalid start value. (Webkit tries to use default.)
element.style[propCamel] = to;
// Iterate through supported prefixes.
for (var i = 0; i < prefixCount; i++) {
// Variations on current prefix.
var prefix = prefixes[i],
hPrefix = (prefix) ? '-' + prefix + '-' : '',
uPrefix = (prefix) ? prefix.toUpperCase() + '_' : '';
// Test for support.
if (CSSRule[uPrefix + 'KEYFRAMES_RULE']) {
// Rule supported; add keyframe rule to test stylesheet.
style.sheet.insertRule('@'+ hPrefix + 'keyframes ' + rule, 0);
// Apply animation.
var animationProp = (hPrefix + 'animation').toCamelCase();
element.style[animationProp] = 'capTest 1s 0s both';
// Get initial computed style.
var before = getComputedStyle(element)[propCamel];
// Skip to last frame of animation.
// BUG: Firefox doesn't support reverse or update node style while
// attached.
doc.removeChild(element);
element.style[animationProp] = 'capTest 1s -1s alternate both';
doc.appendChild(element);
// BUG: Webkit doesn't update style when animation skipped ahead.
element.style[animationProp] = 'capTest 1s 0 reverse both';
// Get final computed style.
var after = getComputedStyle(element)[propCamel];
// If before and after are different, property and values are animable.
canAnimate = before !== after;
break;
}
}
// Clean up the test elements.
doc.removeChild(element);
doc.removeChild(style);
return canAnimate;
}
// Cribbed from Lea Verou's prefixfree.
String.prototype.toCamelCase = function() {
return this.replace(/-([a-z])/g, function($0, $1) { return $1.toUpperCase(); })
.replace('-','');
};
Как использовать
Обязательными аргументами для этого являются свойство для анимации и начальное и конечное значения, которые оно должно принимать. При желании вы можете передать элемент с другим исходным набором стилей, например. position: absolute. (Функция клонирует элемент, так что вы можете передавать узлы из документа, и они не будут изменены.) Если вы не передаете какой-либо элемент, анимация тестируется на div с любыми стилями по умолчанию, применяемыми АП.
Как это работает
Правило анимации по ключевым кадрам добавляется в фиктивную таблицу стилей, где для начального кадра устанавливается значение from, а для конечного кадра — значение to. Эта анимация применяется к элементу. Затем мы проверяем вычисленный стиль для анимированного свойства, чтобы увидеть, отличается ли он, когда анимация начинается с начального кадра, по сравнению с тем, когда она начинается с последнего кадра.
Причина, по которой это работает, заключается в том, что свойства анимации для переходов и анимации ключевых кадров одинаковы, и браузер будет применять значения ключевых кадров только в том случае, если свойство поддерживает анимацию.
Предостережения (прочитайте перед использованием, некоторые из них неприятны!)
Есть несколько несоответствий в том, как браузеры обрабатывают анимацию. Пару из них я обработал как можно более перспективным способом; однако некоторые из них неразрешимы.
В частности, Firefox анимирует значения позиции (например, left) для статических элементов, в то время как другие (например, Webkit и Opera) этого не делают. На самом деле он не перемещает элемент, но значение этого свойства обновляется. Таким образом, вы получите разные результаты в разных браузерах, если попытаетесь анимировать значение позиции без передачи нестатически позиционированного элемента.
Самые последние версии основных браузеров, которые поддерживают переходы CSS, также поддерживают ключевые кадры CSS, хотя некоторые более старые версии поддерживают первое, но не второе. (Например, Опера 11.)
Наконец, если бы я делал это более элегантно, я бы использовал prefixfree, чтобы определить правильный префикс для использования напрямую. ; в настоящее время я тестирую массив префиксов, начиная с версии без префикса.
person
Jordan Gray
schedule
26.06.2012