jQuery: анимация с прыжками / сдвигами по высоте - PullRequest
0 голосов
/ 29 февраля 2012

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

Код выглядит так:

function closeMessage(message) {
    var height = $(message).outerHeight();
    $(message).fadeTo("fast", 0.01).animate({marginTop: -height, marginBottom: 0}, function(){
        $(message).remove();
    });
}

Переменная message - это элемент, который нужно удалить. Внутри CSS я назначил margin-top и margin-bottom элементу сообщения.

Когда вышеупомянутая функция выполняется, элемент сообщения становится непрозрачным до 0,01% (= почти невидимым, но все еще там), а затем отрицательное поле создает эффект, что содержимое под элементом сообщения перемещается вверх. После этого в обратном вызове элемент сообщения удаляется из DOM.

Проблема в том, что содержимое под элементами сообщений переходит на несколько последних пикселей вверх, как небольшой толчок. Этот толчок заметен только при наличии более одного окна сообщения. Это также становится более заметным, чем больше поля установлены. Как видите, я пытался решить проблему с marginBottom: 0, но она не работает.

Я также пробовал в jQuery различные функции height();, такие как outerHeight();, outherHeight(true); и innerHeight();, но это не решило проблему.

Итак, мои вопросы: что-то не так в приведенном выше коде? Почему происходит этот маленький «прыжок» в конечной фазе анимации? Это нормальное поведение?

Ответы [ 2 ]

1 голос
/ 29 февраля 2012

Первая проблема заключается в том, что outerHeight не учитывает поля без передачи true:

var height = $(message).outerHeight(true);
$(message).fadeTo("fast", 0.01).animate({marginTop: -height, marginBottom: 0}, function(){
    $(message).remove();
});

Вторая проблема заключается в том, что по определению CSS вертикальные поля смежных элементов разрушаются, то есть нижнее поле перекрывает верхнее поле следующего элемента. Это усложняет расчет, если все верхние / нижние поля не всегда одинаковы.

Редактировать: Я думаю, что следующее должно работать, если у вас нет отрицательных полей или что-то действительно странное:

function closeMessage(message) {
    var pBot = 0;

    if ($(message).prev().length) {
        pBot = parseInt($(message).prev().css('marginBottom'));
    }

    var height = $(message).outerHeight();
    $(message).fadeTo("fast", 0.01).animate({
        marginTop: -height-pBot+'px',
        marginBottom: pBot+'px'
    }, 'linear', function() {
        $(message).remove();
    });
}

Это заставляет удаляющийся элемент сворачивать его верхнее поле, сводя на нет поле элемента над ним и заставляя элемент "исчезать", вычитая его высоту (без полей), в то же время устанавливая свое собственное дно. -положить то же, что и элемент над ним, по существу совпадая с тем, что будет там, когда он исчезнет. Кажется, он работает нормально, и вам нужно беспокоиться только о предыдущем поле, потому что следующее обрабатывается автоматически.

Пример: http://jsfiddle.net/FxR9M/

Мой собственный пример, который помогает увидеть, что происходит: http://jsfiddle.net/5PRy2/2/

0 голосов
/ 29 февраля 2012

Функция jQuery animate использует стандартную функцию замедления, которая называется swing.Попробуйте изменить код, чтобы использовать «линейную» функцию замедления.

$(message).fadeTo("fast", 0.01).animate({marginTop: -height, marginBottom: 0},'linear', function(){
        $(message).remove();
    });

Ознакомьтесь с документацией здесь

...