Подтвердить что ты не робот

JQuery: анимировать удаление свойства CSS

Я визуально "обрушиваю" некоторые элементы DOM, используя jQuery (уменьшая их ширину до 0px и затухая их) следующим образом:

$(".slideoutmenu").animate({ width: 0, opacity: 0 }, function() { $(this).hide(); }); 

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

Обычно, чтобы повторно показать эти элементы, я мог бы просто сделать что-то вроде этого:

$(".slideoutmenu").stop().show().css({ width: '', opacity: 1 });

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

Обычно я делаю это с чем-то похожим на это:

$(this).children(".slideoutmenu").stop().show().animate({ width: 250, opacity: 1 });

Итак, это очевидная попытка:

$(this).children(".slideoutmenu").stop().show().animate({ width: "", opacity: 1 });

Но это не сработает.

В конечном счете проблема здесь - это фиксированное число "250" в приведенном выше примере. Это не работает, потому что ширина переменной. Мне нужно совместить результат использования пустой строки в css setter и "animate"... но я не могу понять, как это сделать. Я попытался заменить "250" на "undefined", "null", "-1", "", и я искал Google... безрезультатно.

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

Спасибо за чтение.

ПОСЛЕДОВАТЕЛЬНОСТЬ:

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

Вот плагин:

(function( $ ){

  $.fn.cacheCss = function( prop ) {  

    return this.each(function() {

      var $this = $(this);


        if (prop instanceof Array)
        {
            for (var pname in prop)
            {
                if ($this.data('cssCache-' + prop[pname]) != undefined)
                    continue;

                $this.data('cssCache-' + prop[pname], $this.css(prop[pname]));
            }
        }
        else
        {
            if ($this.data('cssCache-' + prop) != undefined)
                return $this;

            $this.data('cssCache-' + prop, $this.css(prop));
        }

        return $this;

    });

  };


  $.fn.revertCss = function(settings, prop, animated) {  

    if (settings == null)
        settings = {};

    return this.each(function() {

      var $this = $(this);

        if (prop instanceof Array)
        {
            for (var pname in prop)
            {
                if ($this.data('cssCache-' + prop[pname]) != undefined)
                    settings[prop[pname]] = $this.data('cssCache-' + prop[pname]).replace(/px$/, "");               
            }
        }
        else
        {
            if ($this.data('cssCache-' + prop) != undefined)
                settings[prop] = $this.data('cssCache-' + prop).replace(/px$/, "");
        }

        if (!animated)
          return $this.css(settings);

        return $this.animate(settings);

    });

  };

})( jQuery );

И вот как я смог изменить свой код, чтобы использовать его:

Оригинальная строка, которая устанавливает свойство css:

$(".slideoutmenu").animate({ width: 0, opacity: 0 }, function() { $(this).hide(); }); 

был заменен на:

$(".slideoutmenu").cacheCss('width').animate({ width: 0, opacity: 0 }, function() { $(this).hide(); }); 

Теперь ".cacheCss('width')" кэширует значение свойства css перед выполнением моей анимации.

И строка, которую я должен был "отменить" эти изменения:

$(this).children(".slideoutmenu").stop().show().animate({ width: 250, opacity: 1 });

было заменено следующим:

$(this).children(".slideoutmenu").stop().show().revertCss({ opacity: 1 }, 'width', true);

Теперь ".revertCss(...)" будет использовать кешированные настройки, чтобы вернуть свойство width (анимированное!)

Я также сделал плагин для приема адаптеров, поэтому вы тоже можете это сделать:

.cacheCss(['width', 'height'])

а затем:

.revertCss(null, ['width', 'height'], true)

третий параметр определяет, анимируется ли реверт или нет.

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

Я уверен, что этот штекер может быть БОЛЬШЕ улучшен, но я думал, что было бы неплохо выбросить его в любом случае.

Кроме того, еще один момент - я должен был заменить spirrious "px" в конце значений css... опять же, я уверен, что, вероятно, лучший способ сделать это, но я просто использовал стандартное регулярное выражение,

4b9b3361

Ответ 1

Вы можете сохранить ширину предварительной анимации элемента, используя данные jQuery:

$(".slideoutmenu").each(function(){
    $(this).data('width', $(this).css('width'));
    $(this).animate({ 
        width: 0, 
        opacity: 0 
    }); 
});

$(".slideoutmenu").each(function(){
    $(this).children(".slideoutmenu").stop().animate({ 
        width: $(this).data('width'), 
        opacity: 1 
    });
});