开发者

jQuery animations mess up in IE8 and earlier

Here is my site: http://smartpeopletalkfast.co.uk/jquery/basicDemo12-bugfix-3.htm

It works fine on firefox, chrome, safari and ie9, but messes up in IE8 and 7.

When you click on an image it expands. When you click on another image, any expanded images contract. I think its this second part of the jQuery causing problems. With IE8 and 7 the animation end up in the correct place, but all the images jump around before then.

Here is the code:

    $(".image-div").click(function () {


        var divRefTwo = $(".image-div").not(this);
        $(".image-div").not(this).animate({
                width: '250px',
                left: '0px',
                marginRight: '0px',
                backgroundPosition: '-125px'
            }, 400, function() {
                $(divRefTwo).css('z-index','1');
            });

        if ($(this).css('z-index') == 1) {
            $(this).css('z-index','2');
            $(this).animate({
                width: '500px',
                left: '-125px',
                marginRight: '-开发者_StackOverflow250px',
                backgroundPosition: '0px'
            }, 500, function() {
                //
            });
        }
        else {
            var divRef = this;
            $(this).animate({
                width: '250px',
                left: '0px',
                marginRight: '0px',
                backgroundPosition: '-125px'
            }, 500, function() {
                $(divRef).css('z-index','1');
            });
        }

    });

Does anyone have any ideas why this is happening? Its quite hard to debug as the issue only presents itself while the animation is running.

Thanks

UPDATE- Ive tried adding conditional statements to only run the animation (that shrinks expanded elements) when necessary, but with this it doesn't run at all:

        if ($(".image-div").not(this).css('width') == '500px') {

        $(".image-div").not(this).animate({
                width: '250px',
                left: '0px',
                marginRight: '0px',
                backgroundPosition: '-125px'
            }, 400, function() {
                $(divRefTwo).css('z-index','1');
            });

        }

        else {
        }

UPDATE2 - Ive updated the latest demo here: http://smartpeopletalkfast.co.uk/jquery2/basicDemo12-bugfix-6.htm

The conditional statements prevent the animation from running on divs that aren't supposed to expand anyway. So this has fixed the problem of all the divs jumping about.

However when the animation runs on the clicked on div (like its supposed to), that div still expands weirdly on IE7 and 8. It seems like this is to do with the background-position animating weirdly.


Two things caused this problem

  • IE prior to version 9 does not support background-position, it supports background-position-x and background-position-y

  • jQuery will not switch to supported styles when it should

Forcing jQuery to use supported styles

var default_css = $.css;
$.css = function (elem, name, extra) {
    name = $.camelCase(name);

    // if requested css name is not backgroundPosition then jQuery can handel it
    if (!name.match(/.*backgroundPosition/i) || !elem.currentStyle || elem.currentStyle[name]) return default_css.apply(this, arguments);

    // if backgroundPosition is supported by browser then return backgroundPosition value
    var style = elem.style;
    if (!extra && style && style[name]) return style[name];

    // if we get here browser doesn't support backgroundPosition, we need to fix it
    return default_css(elem, 'backgroundPositionX', extra) + ' ' + default_css(elem, 'backgroundPositionY', extra);
};

Put this script in page right after jQuery-1.6.1 script.

Tested with IE7, IE8, IE9, Chrome, Opera, Firefox and Safari


I have a sneaky suspicion that IE is not updating the CSS values after the animation. This means that when you click on an image the other images are animated again. I checked with this:

$($(".image-div")[0]).css('background-position')

In IE it is undefined. In FF it has the correct value. So the animation is taking place in IE since the value is not there. Why this is I wouldn't know.

It may be an idea to store the state of each image somehow (maybe .data) and then use that to determine whther to restore the image (using your animation).

Try this:

$(".image-div").click(function () {
    // reset expanded images
    $(".image-div").not(this).each(function() {
        if ($(this).css('z-index') == '2') {
            $(this).animate({
                width: '250px',
                left: '0px',
                marginRight: '0px',
                backgroundPosition: '-125px'
            }, 400, function() { $(this).css('z-index','1'); });
        }
    });

    // toggle clicked image
    if ($(this).css('z-index') == 1) {
        $(this).animate({
            width: '500px',
            left: '-125px',
            marginRight: '-250px',
            backgroundPosition: '0px'
        }, 500, function() { $(this).css('z-index','2'); });
    }
    else {
        $(this).animate({
            width: '250px',
            left: '0px',
            marginRight: '0px',
            backgroundPosition: '-125px'
        }, 500, function() { $(this).css('z-index','1'); });
    }

});


Does anyone have any ideas why this is happening?

Yes, it seems to be because the collapse animation is running on all of the other images, it would be far more efficient and should solve your problem if you run the collapse animation on the expanded image only.

I could demonstrate this in a jsfiddle if needed


Your update to your question definitely has the right idea, you only want to run the animation on the expanded image.

You could add a class every time you expand a image .addClass('expanded') and then check for that class. Obviously removing that class once its collapsed again.

Your update does not work because it needs to run through a .each() function

$(this).siblings().each(function(){

 if ($(this).width() == '500px') {

        $(this).animate({
                width: '250px',
                left: '0px',
                marginRight: '0px',
                backgroundPosition: '-125px'
            }, 400, function() {
                $(divRefTwo).css('z-index','1');
            });

        }

});


I've checked out the link you gave. Be sure to validate your html page. Better browsers such as Chrome, Firefox, Safari and all that lot, will understand your html event with a few errors. IE is not as flexible. An html page that is not W3C valid will hold a few suprises.

And the link you gave, is not W3C valid.


Maybe you could try this:

        $(".image-div").not(this).each(function(){
            if ($(this).css('z-index') != 1)
            {
                $(this).animate({
                    width: '250px',
                    left: '0px',
                    marginRight: '0px',
                    backgroundPosition: '-125px'
                }, 400, function() {
                    $(divRefTwo).css('z-index','1');
                });
            }
        });
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜