【问题标题】:jQuery: Animate Removal of CSS PropertyjQuery:动画移除 CSS 属性
【发布时间】:2011-06-10 00:36:27
【问题描述】:

我使用 jQuery 在视觉上“折叠”一些 DOM 元素(通过将它们的宽度缩小到 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”的结果......但我不知道如何做到这一点。我试过用'undefined'、'null'、'-1'、''替换“250”,我搜索了谷歌......无济于事。

我知道我可能会对用户隐藏的元素做一些测量技巧 - 但我无法想象这不是一个相当普遍的问题 - 所以我希望有一个“标准”的方法来做到这一点,或者它是以某种方式构建的,我只是不知道。

感谢阅读。

跟进:

基于 Michael 的善意回应,我整理了一个小型快速而肮脏的插件,以便我可以内联完成此操作。 (也许有人可以扩展插件的想法并使其变得更好)

这是插件:

(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(...)”将使用缓存的设置来恢复我的宽度属性(动画!)

我也让插件接受数组,所以你也可以这样做:

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

然后:

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

第三个参数控制revert是否为动画。

如果您有其他想要同时设置动画的属性(就像我在前面的示例中使用“不透明度”所做的那样),您可以将它们作为第一个参数传递,就像您将对象传递给 .animate( ) 功能。

我确信这个插件可以得到很大的改进,但我认为无论如何把它扔掉可能会很好。

另外,还有一点 - 我必须在 css 值的末尾替换虚假的“px”...再次,我确信可能有更好的方法来做到这一点,但我只是使用了标准的正则表达式.

【问题讨论】:

  • 我不明白移除 width 属性会如何重新显示元素?
  • 固定示例代码以澄清......但这里的想法是:元素开始时没有特定的固定宽度。然后,给它一个宽度 0 来“收缩”它。然后,我知道没有简单的方法来动画删除那个新的固定宽度“0”。
  • 仅供参考:宽度的默认值为'auto',因此要重新显示元素,您应该使用width: 'auto'

标签: jquery css


【解决方案1】:

您可以使用jQuery data 存储元素预动画的宽度:

$(".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 好问题,正确答案。一种或另一种方式,您必须保存原始宽度。不幸的是,即使是 jQuery 也无法计算出元素不显示时 的尺寸。
  • 再次感谢。我将这个基本概念包装为一个快速而肮脏的插件,并将其发布在问题中。谢谢。干杯。
猜你喜欢
  • 2012-01-24
  • 2012-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-13
  • 1970-01-01
  • 2010-11-03
  • 2015-02-08
相关资源
最近更新 更多