You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何为点击切换位置的行添加平滑滑动动画效果?

给行移动添加平滑滑动动画

首先,先帮你修正原代码的语法小问题(少了闭合的括号和分号),你的核心逻辑是没问题的:

$(".row").each(function() { 
  $(this).click(function(){ 
    if (($(this).next()).length === 1 ) { 
      $(this).insertAfter($(this).next()); 
    } else { 
      $(this).insertBefore($(this).siblings().first()); 
    } 
  }); 
});

要实现平滑的滑动动画,核心是不能让DOM直接瞬间切换位置,而是先通过动画让行“滑”到目标位置,再完成DOM结构的调整。下面给你两种实用的方案:

方案一:CSS Transition + 位移控制(推荐,性能更优)

这种方案用CSS过渡动画配合JavaScript控制位移,性能更好,也更灵活。

首先给行添加基础样式:

.row {
  position: relative;
  transition: transform 0.3s ease; /* 0.3秒平滑过渡,可按需调整时长 */
  cursor: pointer; /* 给用户可点击的视觉提示 */
  margin: 8px 0; /* 加一点间距,动画效果更明显 */
}

/* 临时类,确保移动中的行在最上层,避免被其他行遮挡 */
.row.moving {
  z-index: 10;
}

然后修改JavaScript代码,在DOM插入前先让行滑到目标位置,动画结束后再调整结构:

$(".row").click(function() {
  const $currentRow = $(this);
  const $parentContainer = $currentRow.parent();
  let $targetRow;

  // 确定目标行:非最后一行则移到下一行后,否则移到第一行前
  if ($currentRow.next().length === 1) {
    $targetRow = $currentRow.next();
  } else {
    $targetRow = $parentContainer.children().first();
  }

  // 计算滑动距离:目标行顶部偏移 - 当前行顶部偏移
  const currentOffset = $currentRow.offset().top;
  const targetOffset = $targetRow.offset().top;
  const slideDistance = targetOffset - currentOffset;

  // 标记移动状态,启动滑动动画
  $currentRow.addClass('moving');
  $currentRow.css('transform', `translateY(${slideDistance}px)`);

  // 等待动画结束后调整DOM,再重置样式
  setTimeout(() => {
    if ($currentRow.next().length === 1) {
      $currentRow.insertAfter($targetRow);
    } else {
      $currentRow.insertBefore($targetRow);
    }
    // 重置位移,让行回到正常布局
    $currentRow.css('transform', 'translateY(0)');
    // 等过渡结束后移除移动类,避免影响后续点击
    setTimeout(() => {
      $currentRow.removeClass('moving');
    }, 30);
  }, 300); // 这个时间要和CSS transition的时长保持一致
});

方案二:jQuery animate方法(更简单,适合jQuery重度使用者)

如果你更习惯用jQuery自带的动画方法,可以试试这个方案:

先给行加基础样式:

.row {
  position: relative;
  cursor: pointer;
  margin: 8px 0;
}

然后修改JavaScript代码:

$(".row").click(function() {
  const $currentRow = $(this);
  const $parentContainer = $currentRow.parent();
  let $targetRow, slideToPosition;

  // 确定目标位置和滑动终点
  if ($currentRow.next().length === 1) {
    $targetRow = $currentRow.next();
    slideToPosition = $targetRow.position().top;
  } else {
    $targetRow = $parentContainer.children().first();
    // 最后一行移到顶部时,先滑到容器上方,再插入到第一行前
    slideToPosition = $targetRow.position().top - $parentContainer.height();
  }

  // 执行滑动动画,结束后调整DOM结构
  $currentRow.animate({
    top: slideToPosition
  }, 300, function() {
    // 动画结束后完成DOM插入
    if ($currentRow.next().length === 1) {
      $currentRow.insertAfter($targetRow);
    } else {
      $currentRow.insertBefore($targetRow);
    }
    // 重置top属性,避免影响后续布局
    $currentRow.css('top', 0);
  });
});

小提示

  • 你可以调整动画时长(比如把300改成500就是0.5秒)和缓动函数(比如把ease换成linear或者ease-in-out)来适配你的UI风格。
  • 确保父容器的position不是默认的static(可以设成relative),这样offset()position()的计算才会准确。
  • 如果行的高度不固定,方案一的偏移计算依然有效,因为它是基于元素实际的页面偏移来计算的。

内容的提问来源于stack exchange,提问作者abshi

火山引擎 最新活动