【问题标题】:jquery animate for element attributes not style元素属性的jQuery动画不是样式
【发布时间】:2013-06-25 23:49:37
【问题描述】:

ASAIK jquery animate 函数只接受样式属性。但我想为元素的属性设置动画。考虑一个 SVG 元素矩形

<svg>
<rect id="rect1" x=10 y=20 width="100px" height="100px">
</svg>

我想为矩形元素属性“x”和“y”设置动画,如下所示

$("#rect1").animate({
    x: 30,
    y: 40
  }, 1500 );

但这不是正确的方法,因为动画功能影响样式而不是元素的属性。

我知道有很多自定义插件,例如 raphel.js

http://raphaeljs.com/

但我不想使用自定义插件来执行此操作。我想在 jquery.animate 函数中简单地做到这一点。

这可能吗?

谢谢,

湿婆

【问题讨论】:

标签: jquery svg jquery-animate jquery-svg


【解决方案1】:

只用老式的方式制作动画:

你可以像 jquery 一样调用animate

http://jsfiddle.net/wVv9P/7/

function animate($el, attrs, speed) {

    // duration in ms
    speed = speed || 400;

    var start = {}, // object to store initial state of attributes
        timeout = 20, // interval between rendering loop in ms
        steps = Math.floor(speed/timeout), // number of cycles required
        cycles = steps; // counter for cycles left

    // populate the object with the initial state
    $.each(attrs, function(k,v) {
        start[k] = $el.attr(k);
    });

    (function loop() {
        $.each(attrs, function(k,v) {  // cycle each attribute
            var pst = (v - start[k])/steps;  // how much to add at each step
            $el.attr(k, function(i, old) {
                return +old + pst;  // add value do the old one
            });
        });

        if (--cycles) // call the loop if counter is not exhausted
            setTimeout(loop, timeout);
        else // otherwise set final state to avoid floating point values
            $el.attr(attrs);

    })(); // start the loop
}

$('button').on('click', function() {       
    animate(
        $('#rect1'), // target jQuery element
        { x:100, y:300, width:50, height:100 }, // target attributes
        2000 // optional duration in ms, defaults to 400
    );
});

【讨论】:

  • 您能否详细解释一下。什么是步数、速度和超时功能?这里是什么?你能更具体些吗
【解决方案2】:

我会尝试这样的事情

<svg>
    <rect class="myElement" id="rect1" x="10" y="20" width="100px" height="100px">
</svg>

在脚本中:

var myElemX = $('.myElement').attr('x');
var myElemY = $('.myElement').attr('y');
$("#rect1").animate({
    left: myElemX+'px',
    top:  myElemY+'px'
}, 1500 );

【讨论】:

  • 谢谢。如果我使用 left 和 top 意味着元素中仍然存在 x 和 y 属性。那么位置元素需要什么?
【解决方案3】:

好吧,这里的所有答案要么特定于 SVG,要么重新实现 .animate() jQuery 调用,我找到了一种使用 jQuery 调用的方法,而不会遇到动画开始时属性重置为 0 的问题:

假设我们想要为 id 为 image 的 img 标签元素的 widthheight 属性设置动画。要将其从当前值设置为 300 的动画,我们可以这样做:

var animationDiv= $("<div></div>"); //we don't add this div to the DOM
var image= $("img#image");
//could use any property besides "top" and "left", but the value must be valid, that means concatenating a "px" to numerical attributes if they don't have it already (and removing them in the step callback if they do)
animationDiv.css("left", image.attr("width")); 
animationDiv.css("top", image.attr("height")); 
animationDiv.animate(
    {
        left: 300,
        top: 300
    },
    {
        duration: 2500,
        step: function(value, properties) {
            if (properties.prop == "left")
                 image.attr("width", value + "px")
            else
                 image.attr("height", value + "px")
        }
    }
)

在这种方法中,我们使用一个不在 DOM 内部的 div 并在其中设置动画值,然后我们使用 div CSS 值来为我们的元素设置动画。不是很漂亮,但可以完成工作,如果您需要停止动画,您可以在 animationDiv 上调用 .stop()

jsfiddle

【讨论】:

  • 投票结束该问题作为您刚刚用此答案回答的另一个问题的副本不是更好吗?
【解决方案4】:

我喜欢 Hoffmann 方法,但我认为不创建虚拟 dom 对象会更优雅。

这是我的咖啡脚本 sn-p

$rects.each ->
  that = @
  $({width: 0}).animate
  width: parseInt($(@).attr('width'))
  ,
  duration: 2000
  easing: 'easeIn'
  step: ->
    $(that).attr 'width', Math.round(@.width)
  done: ->
    console.log 'Done'

编译成

return $rects.each(function() {
  var that;
  that = this;
  return $({
    width: 0
  }).animate({
    width: parseInt($(this).attr('width'))
  }, {
    duration: 1000,
    easing: 'easeIn',
    step: function() {
      return $(that).attr('width', Math.round(this.width));
    },
    done: function() {
      return console.log('Done');
    }
  });
});

【讨论】:

    【解决方案5】:

    这可能很适合你

    $("your div id").css("position", "absolute").animate({
        left: 159,
        top:  430
    });
    

    【讨论】:

    • 据我所知,“top”和“left”将是css属性。这个问题明确地说“元素属性不是样式”。如果我错了,我会删除反对票
    猜你喜欢
    • 2011-03-30
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    相关资源
    最近更新 更多