JQuery анимации беспорядок в IE8 и ранее

Вот мой сайт: http://smartpeopletalkfast.co.uk/jquery/basicDemo12-bugfix-3.htm

Он отлично работает на firefox, chrome, safari и ie9, но запутывается в IE8 и 7.

Когда вы нажимаете на изображение, оно расширяется. Когда вы нажимаете на другое изображение, любые расширенные изображения сжимаются. Я думаю, что эта вторая часть jQuery вызывает проблемы. С IE8 и 7 анимация заканчивается в правильном месте, но все изображения прыгают до этого.

Вот код:

    $(".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: '-250px',
                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');
            });
        }

    });

Есть ли у кого-нибудь идеи, почему это происходит? Его довольно сложно отладить, поскольку проблема возникает только во время анимации.

Спасибо

UPDATE-Ive попытался добавить условные операторы только для запуска анимации (которая сжимает расширенные элементы), когда это необходимо, но при этом она не запускается вообще:

        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 обновил последнюю демо: http://smartpeopletalkfast.co.uk/jquery2/basicDemo12-bugfix-6.htm

Условные утверждения не позволяют анимации запускаться в div, которые не должны расширяться. Таким образом, это фиксировало проблему всех прыжков с div.

Однако, когда анимация запускается при нажатии на div (как и предполагалось), этот div по-прежнему значительно расширяется на IE7 и 8. Похоже, что это связано с тем, что анимация в фоновом режиме анимируется странно.

Ответы

Ответ 1

У меня есть подозрительное подозрение, что IE не обновляет значения CSS после анимации. Это означает, что при нажатии на изображение другие изображения снова анимируются. Я проверил с этим:

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

В IE это undefined. В FF оно имеет правильное значение. Таким образом, анимация происходит в IE, поскольку ее значение отсутствует. Почему я этого не знаю.

Может быть, идея каким-то образом сохранить состояние каждого изображения (возможно, .data), а затем использовать это, чтобы определить, как восстановить изображение (используя вашу анимацию).

Попробуйте следующее:

$(".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'); });
    }

});

Ответ 2

Две проблемы вызвали эту проблему

  • IE до версии 9 не поддерживать фоновое положение, оно поддерживает background-position-x и background-position-y

  • jQuery не будет переключитесь на поддерживаемые стили, когда он следует

Принуждение jQuery к использованию поддерживаемых стилей

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);
};

Поместите этот script на страницу сразу после jQuery-1.6.1 script.

Протестировано с помощью IE7, IE8, IE9, Chrome, Opera, Firefox и Safari

Ответ 3

Есть ли у кого-нибудь идеи, почему это происходит?

Да, похоже, потому, что анимация коллапса работает на всех других изображениях, она будет намного более эффективной и должна решить вашу проблему, если вы запускаете анимацию коллапса только на расширенном изображении.

Я мог бы продемонстрировать это в jsfiddle при необходимости


Ваше обновление вашего вопроса, безусловно, имеет правильную идею, вы хотите только запустить анимацию на расширенном изображении.

Вы можете добавлять класс каждый раз, когда вы расширяете образ .addClass('expanded'), а затем проверяете этот класс. Очевидно, удалив этот класс, как только он снова рухнет.

Ваше обновление не работает, потому что ему нужно выполнить функцию .each()

$(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');
            });

        }

});

Ответ 4

Я проверил ссылку, которую вы дали. Обязательно проверьте свою страницу html. Лучшие браузеры, такие как Chrome, Firefox, Safari и многое другое, поймут ваше html-событие с несколькими ошибками. IE не такой гибкий. На странице html, которая не является допустимой W3C, будет несколько сюрпризов.

И ссылка, которую вы дали, не действительна W3C.

Ответ 5

Возможно, вы могли бы попробовать следующее:

        $(".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');
                });
            }
        });