Jump to content
Search Community

True IE8 className based tweens fail certain properties

iamjem test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Been looking further at the TweenMax source code and it seems to relate to getComputedStyle which IE8 doesn't sport natively and is used with className based tweens to determine prop differences.

 

Even after including a polyfill (and perhaps this is the polyfills fault) doesn't seem to patch anything up (I'm looking at https://github.com/jonathantneal/Polyfills-for-IE8/blob/master/getComputedStyle.js), namely because TweenMax points to defaultView.getComputedStyle as oppose to window.getComputedStyle. Altering the polyfill or TweenMax so the polyfill actually gets leveraged just winds up spitting errors (props returned are already camel case from the polyfill, might relate to that).

 

Will keep looking...

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...