As I needed a solution to this where I could continue to use className tweens for IE8, I wrote some utility methods that has fixed the problem for my project. I'm largely doing the same thing TweenMax does internally, but as noted there is some mysterious problems with certain properties in the current version of TweenMax, namely for me the top property (which is also demonstrated in the fiddle at the start of the post). I am using jQuery in this code.
// factory function for building tweens
var makeClassNameTween = function (selector, duration, opts1, opts2) {
var method = "to";
if (opts2 !== undefined) {
method = "fromTo";
}
if (!$("html").hasClass("ie8") || window.getComputedStyle) {
return TweenMax[method].apply(TweenMax, arguments);
}
else {
var element = $(selector)[0],
_realTween = null;
var delay = (opts2 && opts2.hasOwnProperty("delay")) ? opts2.delay : (opts1.hasOwnProperty("delay")) ? opts1.delay : 0;
var tween = TweenMax.to({ value: 0 }, duration, {
value: 1,
delay: delay,
onUpdate: function () {
if (_realTween === null) {
var args = [element, duration, { css: getCssDiff(element, opts1.className) }];
if (method === "fromTo") {
args.push({
css: getCssDiff(element, opts1.className, opts2.className)
});
}
args[args.length - 1].paused = true;
_realTween = TweenMax[method].apply(TweenMax, args);
}
_realTween.progress(this.progress());
}
});
if (method === "fromTo") {
tween.progress(0.1);
tween.progress(0);
}
return tween;
}
};
var currStyleExtend = function (currStyle) {
var ret = {}, key;
for (key in currStyle) {
try {
ret[key] = currStyle[key];
}
catch (e) { }
}
return ret;
};
// for IE8, finds the CSS differences with and without a className
var getCssDiff = function (element, className1, className2) {
var inlineCss = element.style.cssText;
var diffCss = {};
var currCss, newCss;
className1 = className1.replace(/^\+\=/, "");
// clear inline styles
element.style.cssText = "";
if (className2 === undefined) {
currCss = currStyleExtend(element.currentStyle);
$(element).addClass(className1);
newCss = currStyleExtend(element.currentStyle);
$(element).removeClass(className1);
}
else {
className2 = className2.replace(/^\+\=/, "");
$(element).addClass(className1);
currCss = currStyleExtend(element.currentStyle);
$(element).addClass(className2);
newCss = currStyleExtend(element.currentStyle);
$(element).removeClass(className1 + " " + className2);
}
// replace inline CSS
element.style.cssText = inlineCss;
// calculate diffs
var key;
for (key in newCss) {
if (currCss[key] !== newCss[key]) {
diffCss[key] = newCss[key];
}
}
return diffCss;
};
// example usage for TweenMax.to
makeClassNameTween(".selector", 0.5, {
className: "+=newClass"
});
// example usage for TweenMax.fromTo
makeClassNameTween(".selector", 0.5, {
className: "+=newClass1"
}, {
className: "+=newClass2"
});
I will be happy to remove this if the problem gets resolved. For non-IE8 browsers the makeClassNameTween just returns the normal TweenMax instance with the supplied arguments.
UPDATE: apparently $.extend with element.currentStyle explodes. Some of the keys returned when looping over currentStyle must be "special", added method that try catches to silence them.