这是我目前的解决方案 - 有点hacky,只有在知道可能转换的元素时才起作用,并且不适用于 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,
singletonCallback = function () {
if (!callbackHasRun) {
callbackHasRun = true;
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);
setTimeout(singletonCallback, duration * 1000);
return;
}
}
singletonCallback();
}, 20);
}
getComputedStyle
读取transition-property
,然后获取列出的所有属性的值,然后应用类,然后再次使用getComputedStyle
并阅读所有属性,以查看它们是否已更改(我甚至不确定规范是否表示如果有转换定义,它们应立即更改,还是在重绘之前?)我还需要考虑当一个错误意味着事件没有触发时的回退。考虑到供应商前缀,这将成为一个庞大的函数。 - wheresrhys