如何在不使用变换或上/左的情况下转换列表中项目的位置
Posted
技术标签:
【中文标题】如何在不使用变换或上/左的情况下转换列表中项目的位置【英文标题】:How is it possible to transition the position of items in a list without using transform or top/left 【发布时间】:2018-09-27 15:33:49 【问题描述】:前几天我偶然发现了使用 Vue.js 的 an example,但我的问题更多是关于 Vue 用于实现状态之间转换的 CSS 和 html。
卡片暂时获得 .shuffleMedium-move
类,它添加了一个 transition: transform 1s
并且节点的顺序在 DOM 中发生了变化,但我不明白为什么会发生转换,因为 transform
属性似乎从未设置并且项目只需使用float:left
定位。
我做 CSS 已经有一段时间了,我总是不得不使用 javascript position: absolute
和 transform
的组合来获得类似的结果。 Vue的解决方案看起来很优雅,但我不明白它是如何工作的。
【问题讨论】:
动画是通过类完成的,而您在检查时看不到这些类,因为它们会立即添加/删除。但是,如果你在 shuffle 函数中添加debugger
行,在 vue(...) 行之后并检查 dom,你会看到其他类。您必须先检查卡然后运行代码,如果您运行代码并开始调试,您可能无法检查
hmm 我没有看到除了 shuffleMedium-move
之外添加的任何其他类,它只添加了 transition: transform 1s
我希望还会看到类似:shuffleMedium-start
或 shuffleMedium-end
或添加内联样式,但是 vuejs 似乎并没有做任何事情。
transform
确实很快被内联添加,然后立即删除。
@duprasa 这些类被添加然后删除,你不会在检查器中看到它们。我测试了 25 秒的转换时间,当我在调试器中设置断点时,我能够看到类
【参考方案1】:
来自documentation on list transition
这可能看起来很神奇,但实际上,Vue 使用了一种名为 FLIP 的动画技术,通过变换将元素从旧位置平滑过渡到新位置。
来自FLIP article
FLIP 代表 First、Last、Invert、P躺着。
让我们分解一下:
First:过渡中涉及的元素的初始状态。 Last:元素的最终状态。 反转:这是有趣的部分。你从第一个和最后一个元素中找出了元素是如何变化的,所以——比如说——它的宽度、高度、 不透明度。接下来,您应用变换和不透明度更改来反转,或者 倒置,他们。如果元素在 First 和 最后,您将在 Y 中应用 -90px 的变换。这使得 元素看起来好像它们仍然在第一个位置但是, 至关重要的是,它们不是。 播放:为您更改的任何属性打开过渡,然后移除反转更改。因为元素或 元素处于其最终位置,移除变换和 不透明度将使它们从虚假的第一位置缓解到 最后一个位置。
分步示例
这样,我们可以检查动画过程每一步的变化。
在实时播放时,transform
会很快被内联添加,然后立即删除,所以看起来它从未设置过。
var $el = $('.target');
var el = $el.get(0);
var data = ;
function first()
data.first = el.getBoundingClientRect();
console.log('First: get initial position', data.first.left, 'px');
function last()
$el.toggleClass('last');
data.last = el.getBoundingClientRect();
console.log('Last: get new position', data.last.left, 'px');
function invert()
var invert = data.first.left - data.last.left;
el.style.transform = `translateX($invertpx)`;
console.log('Invert: applies a transform to place the item where it was.');
function play()
requestAnimationFrame(function()
$el.addClass('animate');
el.style.transform = '';
);
console.log('Play: adds the transition class and removes the transform.');
function end()
$el.removeClass('animate');
console.log('End: removes the transition class.');
var steps = [first, last, invert, play, end];
var step = 0;
function nextStep()
steps[step++ % steps.length]();
$('button').click(nextStep);
.last
margin-left: 35px;
.animate
transition: transform 1s;
.target
display: inline-block;
padding: 5px;
border: 1px solid #aaa;
background-color: #6c6;
<div class="target">target</div>
<br>
<button type="button">Next</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
【讨论】:
感谢您的详细回答:)。我将对此进行大量实验,我仍然很惊讶 chrome 没有显示内联transform
,即使它几乎是瞬时的。以上是关于如何在不使用变换或上/左的情况下转换列表中项目的位置的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 foreach 的情况下将 ArrayList 转换为强类型泛型列表?
在不使用 opencv 的情况下在 python 中应用 Homography 变换
如何在不使用 for 循环的情况下将列表中的所有项目与整数进行比较