有没有一种方法可以在不定义任何属性的情况下使用CSS过渡?

问题描述 投票:0回答:1

我有一个 JavaScript 函数可以在父 div 上移动不同的子元素,但我想添加一个过渡,以便元素移动到 div 中的新位置,而不是立即更改位置。就我使用的过渡而言,对我来说它仅适用于定义的属性,例如顶部/底部或高度/宽度。在这种情况下,我没有定义任何属性,所以我想知道是否仍然可以实现过渡效果。

在这里你可以看到我设置的孩子和家长:

  <div id="parent">
    <div id="child1" style="background-color:red" class="child">
      <p>child1</p>
    </div>
        <div id="child2" style="background-color:lightblue" class="child">
      <p>child2</p>
    </div>
        <div id="child3" style="background-color:green" class="child">
      <p>child3</p>
    </div>
        <div id="child4" style="background-color:yellow" class="child">
      <p>child4</p>
    </div>
  </div>

以及我移动子元素的函数:

function moveElement(elementId, place){
    let div = document.getElementById('parent')
    let element = document.getElementById(String(elementId))
    let referencenode = div.children[place]
    div.insertBefore(element, referencenode)
}

var children = document.getElementById('parent').children;

document.addEventListener("click", function(event){
    let id = children.item(2).id;
    moveElement(id, 0)
});

由于我所有的工作转换尝试都失败了,所以我只留下了开关功能,所以它们立即交换了位置。

我尝试使用过渡持续时间,但由于没有定义 CSS 属性,就像预期的那样什么也没有发生。

提前致谢! 请不要使用 jQuery,因为我从来没有使用过它,所以如果可能的话,我会很感激普通的 JavaScript :)

javascript html css css-transitions
1个回答
0
投票

正如评论所暗示的,CSS 转换发生在 CSS 属性更改时,因此必须更改某些 CSS 属性才能发生转换。对于顺序或 DOM 元素的动画更改,您可以考虑使用 First、Last、Invert、Play (FLIP) 技术1234,其中:

  1. First:获取元素的初始位置。
  2. Last:使元素达到其结束状态。
  3. 反转:使用前面步骤中的信息将位置更改反转回更改发生之前元素的外观。
  4. Play:删除反转但使用过渡,以便元素从反转动画回到新位置。

function moveElement(elementId, place) {
  let div = document.getElementById('parent')
  let element = document.getElementById(String(elementId))
  
  const children = Array.from(element.parentElement.children);
  let referencenode = children[place]
  
  // Get the child index of the element being moved.
  const elementIndex = children.indexOf(element);
  // Get the list of elements that will move.
  const movingChildren = children.slice(
    elementIndex > place ? place : elementIndex,
    (elementIndex > place ? elementIndex : place) + 1,
  );
  
  // Capture the positions of the elements being moved (First).
  const before = movingChildren.map(
    movingChild => movingChild.getBoundingClientRect(),
  );  
  
  // Do the moving (Last).
  div.insertBefore(element, referencenode);
  
  // Do the animations.
  movingChildren.forEach((child, i) => {
    // Get the moved position.
    const newPosition = child.getBoundingClientRect();
    // `transform` the element back to their old position (Invert).
    child.style.transform = `translate(${before[i].x - newPosition.x}px, ${before[i].y - newPosition.y}px)`;
    
    // Initialize the transition on the next render frame.
    requestAnimationFrame(() => {
      // Clear transitioning.
      const clearTransition = () => {
        child.style.transition = '';
        child.removeEventListener('transitionend', clearTransition);
      };
      child.addEventListener('transitionend', clearTransition);
      
      // Do the transition (Play).
      child.style.transition = 'transform 250ms';
      child.style.transform = '';
    });
  });  
}

var children = document.getElementById('parent').children;

document.addEventListener("click", function(event) {
  let id = children.item(2).id;
  moveElement(id, 0)
});
<div id="parent">
  <div id="child1" style="background-color:red" class="child">
    <p>child1</p>
  </div>
  <div id="child2" style="background-color:lightblue" class="child">
    <p>child2</p>
  </div>
  <div id="child3" style="background-color:green" class="child">
    <p>child3</p>
  </div>
  <div id="child4" style="background-color:yellow" class="child">
    <p>child4</p>
  </div>
</div>


1布局动画FLIP技术
2使用 FLIP 技术实现布局动画
3翻转你的动画
4动画不可动画

© www.soinside.com 2019 - 2024. All rights reserved.