javascript jQuery - animate将DOM元素移动到新的父元素?

zujrkrfu  于 2023-06-20  发布在  Java
关注(0)|答案(9)|浏览(123)

我在一个表格单元格中有一个图像标记,我想将它移动到 * 另一个 * 表格单元格中,并将该移动设置为动画。
代码看起来像这样…

<td id="cell1"><img src="arrow.png" alt="Arrow"/></td>
<td id="cell2"></td>

我想把“arrow.png”移到“cell 2”,并有某种过渡效果,最好用jQuery。
有什么想法吗
谢谢!

w9apscun

w9apscun1#

这实际上相当困难,因为您必须将其删除并添加到DOM中,但要保持其位置。我觉得你在找这样的东西。基本上,我们不会在#cell1#cell2中设置箭头的动画。我们只需要在body-标签中创建一个新的,并将其动画化。这样我们就不必担心表格单元格的位置,因为我们可以相对于文档进行定位。

var $old = $('#cell1 img');
//First we copy the arrow to the new table cell and get the offset to the document
var $new = $old.clone().appendTo('#cell2');
var newOffset = $new.offset();
//Get the old position relative to document
var oldOffset = $old.offset();
//we also clone old to the document for the animation
var $temp = $old.clone().appendTo('body');
//hide new and old and move $temp to position
//also big z-index, make sure to edit this to something that works with the page
$temp
  .css('position', 'absolute')
  .css('left', oldOffset.left)
  .css('top', oldOffset.top)
  .css('zIndex', 1000);
$new.hide();
$old.hide();
//animate the $temp to the position of the new img
$temp.animate( {'top': newOffset.top, 'left':newOffset.left}, 'slow', function(){
   //callback function, we remove $old and $temp and show $new
   $new.show();
   $old.remove();
   $temp.remove();
});

我想这会给你指明正确的方向。

bvuwiixz

bvuwiixz2#

@Pim Jager的答案很好,但是如果你有对原始元素的对象引用,它们会中断,因为原始元素被一个克隆替换了
我想出了一个我认为稍微干净一点的解决方案,它只有一个克隆,显示动画,然后消失,把原来的留在新的位置。

function moveAnimate(element, newParent){
    //Allow passing in either a jQuery object or selector
    element = $(element);
    newParent= $(newParent);

    var oldOffset = element.offset();
    element.appendTo(newParent);
    var newOffset = element.offset();

    var temp = element.clone().appendTo('body');
    temp.css({
        'position': 'absolute',
        'left': oldOffset.left,
        'top': oldOffset.top,
        'z-index': 1000
    });
    element.hide();
    temp.animate({'top': newOffset.top, 'left': newOffset.left}, 'slow', function(){
       element.show();
       temp.remove();
    });
}

用途:moveAnimate('#ElementToMove', '#newContainer')

35g0bw71

35g0bw713#

你需要分两步来做:(1)动画(2)回归。
正如@Ballsacian指出的那样,你可以用.animate()来处理动画。rehoming可以用.html()来完成-对于上面的例子,

var arrowMarkup = $('#cell1').html(); //grab the arrow
$('#cell1').html(""); //delete it from the first cell
$('#cell2').html(arrowMarkup); //add it to the second cell

当然,您必须使代码复杂化以集成动画。这种方法不会导致选择(我假设您选择的是表行?)激活旧选择和新选择之间的行。那就更复杂了。

kmynzznz

kmynzznz4#

我对one of the other answers进行了进一步的扩展,现在您可以将一个对象作为第三个参数传递,该参数在动画期间充当车辆。例如,如果你想把一些从一个移动到另一个,你可能有一个特定的类,它给它的样式。因此,在一个临时车辆内设置动画非常方便,该车辆提供与动画源或目标相同的样式: to another, your likely has a certain class that gives the its styling. So, it would really be handy to animate your inside a temporary vehicle that provides for the same styling as either the source or the target of the animation:

//APPENDS AN ELEMENT IN AN ANIMATED FASHION
function animateAppendTo(el, where, float){
    var pos0 = el.offset();
    el.appendTo(where);
    var pos1 = el.offset();
    el.clone().appendTo(float ? float : 'body');
    float.css({
        'position': 'absolute',
        'left': pos0.left,
        'top': pos0.top,
        'zIndex': 1000
    });
    el.hide();
    float.animate(
        {'top': pos1.top,'left': pos1.left},
        'slow',
        function(){
           el.show();
           float.remove();
        });
}
kd3sttzy

kd3sttzy5#

我尝试了@Davy8的功能,这是相当不错的,但我发现它相当不和谐时,移动的元素抢购了页面在开始,然后在结束。其他页面元素的突然移动打断了原本平滑的动画,但这可能取决于您的页面布局。
所以这是@Davy8函数的修改版本,它也应该平滑地缩小和增加父节点之间的空间。

function moveAnimate(element, newParent,
                     slideAnimationSpeed/*=800*/, spacerAnimationSpeed/*=600*/)
{
    //Allow passing in either a jQuery object or selector
    element = $(element);
    newParent= $(newParent);
    slideAnimationSpeed=slideAnimationSpeed||800;
    spacerAnimationSpeed=spacerAnimationSpeed||600;

    var oldOffset = element.offset();
    var tempOutgoing=element.clone().insertAfter(element);
    tempOutgoing.hide(); //Don't take up space yet so 'newOffset' can be calculated correctly
    element.appendTo(newParent);
    var newOffset = element.offset();

    var tempMover = element.clone().appendTo('body');
    tempMover.css({
        'position': 'absolute',
        'left': oldOffset.left,
        'top': oldOffset.top,
        'z-index': 1000,
        'margin':0 //Necessary for animation alignment if the source element had margin
    });

    element.hide();
    element.show(spacerAnimationSpeed).css('visibility', 'hidden'); //Smoothly grow space at the target

    tempMover.animate({'top': newOffset.top, 'left': newOffset.left}, slideAnimationSpeed, function(){
       element.css('visibility', 'visible');
       tempMover.remove();
    });
    tempOutgoing.show().css('visibility', 'hidden');
    tempOutgoing.hide(spacerAnimationSpeed, function(){ tempOutgoing.remove() }); //smoothly shrink space at the source
}
mccptt67

mccptt676#

如果动画不一定是移动的东西,这个使用淡入和淡出的问题给出了一个简单,干净的答案,没有克隆,仍然很好地传达了运动:
Re-ordering div positions with jQuery?

mnowg1ta

mnowg1ta7#

对于任何仍然在看这个的人,我发现提供的例子并不完全符合我想要的,他们没有考虑到利润率,所以这里是我的版本:

jQuery.fn.extend({
    moveElement : function (newParent, speed, after) {
        var origEl   = $(this);
        var moveToEl = $(newParent);

        var oldOffset = origEl.offset();
        var temp      = origEl.clone().appendTo('body');

        temp.css({
            'position' : 'absolute',
            'left'     : parseInt(oldOffset.left) - parseInt(origEl.css('margin-left')),
            'margin'   : origEl.css('margin'),
            'top'      : oldOffset.top,
            'z-index'  : 1000,
            'height'   : moveToEl.innerHeight(),
            'width'    : moveToEl.innerWidth()
        });

        var blankEl = $('<div></div>').css({
            height   : moveToEl.innerHeight(),
            margin   : moveToEl.css('margin'),
            position : 'relative',
            width    : moveToEl.innerWidth()
        });

        if (after) {
            origEl.insertAfter(moveToEl);
            blankEl.insertAfter(newParent);
        }
        else {
            origEl.insertBefore(moveToEl);
            blankEl.insertBefore(newParent);
        }
        origEl.hide();

        var newOffset = blankEl.offset();

        temp.animate({
            'top'  : blankEl.offset().top - parseInt(moveToEl.css('margin-top')),
            'left' : newOffset.left - parseInt(moveToEl.css('margin-left'))
        }, speed, function () {
            blankEl.remove();
            origEl.show();
            temp.remove();
        });
    }
});

将一个图元移动到另一个图元之前:$('.elementToFind').moveElement('.targetElement', 1000);
逐个移动图元:$('.elementToFind').moveElement('.targetElement', 1000, 'after');

g6ll5ycj

g6ll5ycj8#

如果有人正在寻找一个没有jQuery的版本,这是我的vanilla-javascript版本

let myAnimation ={
    // https://youmightnotneedjquery.com/ instead of $.offfset()
    offset: function (elementNode) {
        let box = elementNode.getBoundingClientRect();
        let docElem = document.documentElement;
        return {
            top: box.top + window.scrollY - docElem.clientTop,
            left: box.left + window.scrollX - docElem.clientLeft
        };
    },

    testMove: function() {
        let start = document.getElementById('start');
        let end = document.getElementById('end');
        // calculate direct path
        let oldOffset = this.offset(start);
        let newOffset = this.offset(end);
        let startNode = document.querySelector('#start div');
        // drop element at new position
        end.appendChild(startNode); // transfer the element
        let dy = `${oldOffset.top - newOffset.top}px`;
        let dx = `${oldOffset.left - newOffset.left}px`;
        startNode.style.top = dy;
        startNode.style.left = dx;
        // definition of animation keyframe-like
        const offsetMoveAction = [
            { 'left': dx,'top': dy,  },
            {  'left': 0,'top': 0,  },
        ];
        const offsetMoveTiming = {
            duration: 2000,
            iterations: 1,
            easing: 'ease-in-out',
            fill: 'forwards', // unexpected key for `animation-fill-mode` :-(
        };
        startNode.animate(offsetMoveAction, offsetMoveTiming);
    },

}
// do it
myAnimation.testMove();
<div style="width:200px; height: 200px; position:relative; border: solid 1px red;margin: 20px;">
    <div id="start" style="position:absolute; top:0; left:0;width:15ch;">
        <div style="position:relative; ">
            <div style="position:absolute; top:0; left:0;">drag and drop by JS</div>
        </div>
    </div>
    <div id="end" style="position:absolute; right:0; bottom:1rem;width:16ch;"></div>
</div>
ecr0jaav

ecr0jaav9#

jQuery http://docs.jquery.com/Downloading_jQuery
JQuery Effects http://docs.jquery.com/Effects/animate#paramsoptions
示例

$("#go1").click(function(){
      $("#block1").animate( { width:"90%" }, { queue:false, duration:3000 } )
         .animate( { fontSize:"24px" }, 1500 )
         .animate( { borderRightWidth:"15px" }, 1500);
    });

相关问题