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

#jquery #css

#jquery — jquery — запрос #css

Вопрос:

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

 $(".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 и «анимировать»… но я не могу понять, как это сделать. Я пытался заменить «250» на «undefined», «null», «-1″, » и я искал в Google … безрезультатно.

Я понимаю, что, вероятно, я могу проделать какую-нибудь хитрость с измерением элемента, скрытого от пользователя, — но я не могу представить, что это не довольно распространенная проблема, — поэтому я надеюсь, что есть «стандартный» способ сделать это, или что он встроен каким-то образом, и я просто не знаю об этом.

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

ПОСЛЕДУЮЩИЕ ДЕЙСТВИЯ:

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

Вот плагин:

 (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().

Я уверен, что заглушку можно было бы ЗНАЧИТЕЛЬНО улучшить, но я подумал, что было бы неплохо в любом случае выбросить ее на улицу.

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

Комментарии:

1. Я не понимаю, как удаление атрибута width приведет к повторному отображению элемента?

2. Исправлен пример кода для уточнения… но идея здесь такова: элемент начинается без какой-либо определенной фиксированной ширины. Затем ему присваивается ширина 0, чтобы «сжать» его. Тогда, насколько я знаю, нет простого способа анимировать удаление этой новой фиксированной ширины «0».

3. К вашему сведению: значение width по умолчанию равно ‘auto’, поэтому для повторного отображения элемента вам следует использовать width: 'auto'

Ответ №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 
    });
});
  

Комментарии:

1. 1 Хороший вопрос и правильный ответ. Так или иначе, вы должны сохранить исходную ширину. К сожалению, даже jQuery не может определить, какими были бы размеры, пока элемент не отображается.

2. Еще раз спасибо. Я превратил эту базовую концепцию в быстрый и грязный плагин и опубликовал ее в вопросе. Спасибо. Приветствия.