将元素平稳地移动到新位置而无需手动设置其位置

Moving an element smoothly to its new position without manually setting its position

如果主题有点非描述性,我深表歉意。我很难用一句话解释我想要达到的目标。

但简而言之:我正在尝试让一个元素(在本例中为 DIV)平稳地移动到它的新位置。但需要注意的是,我没有手动设置它的位置。它获得了一个新位置,因为我要从页面流中删除其他 DIV。

<!DOCTYPE html>
<html>
  <head>
    <style>
      .block {
        width: 200px;
        height: 20px;
        border: 1px solid black;
        margin: 20px;
      }
    </style>
    <script>
      function removeBlock() {
        document.getElementById("block2").style.display = "none";
      }
    </script>
  </head>
  <body>
    <div id="block1" class="block">
      This is block 1
    </div>
    <div id="block2" class="block">
      This is block 2
    </div>
    <div id="block3" class="block">
      This is block 3
    </div>

    <button type="button" onclick="removeBlock();">
      Remove block 2
    </button>
  </body>
</html>

这是 fiddle:https://jsfiddle.net/nfhycrkL/

如果点击按钮,Block 2 隐藏,Block 3 向上移动。我希望此举顺利进行。这是可能吗?我不想使用绝对定位,因为页面是响应式的并且 DIV 的位置取决于页面大小。

试试这个解决方案

function removeBlock()
{
  document.getElementById("block2").style.height = "0px";
  document.getElementById("block2").style.margin = "0px";
  document.getElementById("block2").style.borderWidth = "0px";
  document.getElementById("block2").style.fontSize = "0px";
}
.block {
  width: 200px;
  height: 20px;
  border: 1px solid black;
  margin: 20px;
}

#block2 {
  transition:all 0.5s linear;
}
<div id="block1" class="block">
  This is block 1
</div>
<div id="block2" class="block">
  This is block 2
</div>
<div id="block3" class="block">
  This is block 3
</div>

<button type="button" onclick="removeBlock();">
  Remove block 2
</button>

您可以将新的 class 添加到要隐藏的 javascript 元素并进行 css 转换。

这是一个带有删除和切换选项的小示例https://jsfiddle.net/nfhycrkL/9/

html:

<div id="block1" class="block">
  This is block 1
</div>
<div id="block2" class="block">
  This is block 2
</div>
<div id="block3" class="block">
  This is block 3
</div>

<button type="button" onclick="toggleBlock();">
  Toggle block 2
</button>

<button type="button" onclick="removeBlock();">
  Remove block 2
</button>

js :

function toggleBlock() {
  document.getElementById("block2").classList.toggle('block-hidden')
}
function removeBlock() {
  document.getElementById("block2").classList.add('block-hidden')
}

css:

.block {
  width: 200px;
  height: 20px;
  border: 1px solid black;
  margin: 0 20px 20px;
  overflow:hidden;
  transition: all .25s;
}

.block-hidden {
  height: 0px;
  margin: 0px;
  border: none;
}

$(document).ready(function(){
 
  $("button").click(function(){
  //document.getElementById("block2").style.display = "none";
   $("#block2").fadeOut(1000);
  });
});
.block {
  width: 200px;
  height: 20px;
  border: 1px solid black;
  margin: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet"/>

<div id="block1" class="block">
  This is block 1
</div>
<div id="block2" class="block">
  This is block 2
</div>
<div id="block3" class="block">
  This is block 3
</div>

<button type="button">
  Remove block 2
</button>

使用Jquery effects。希望对您有所帮助。

这是 vanillaJS 中的一个简单示例,带有 CSS 转换

Jsfiddle demo


更新您的样式,为 .block 元素添加过渡效果

CSS

.block {
  width: 200px;
  height: 20px;
  border: 1px solid black;
  margin: 20px 20px 0;
  max-height: 500px;
  transition: opacity 0s 0s, margin .25s 0s, max-height .25s 0s;
}

.removedBlock {
  box-sizing: border-box;
  opacity: 0;
  margin: 0;
  max-height: 0;
}

以便函数可以通过添加 removedBlock class

来触发 max-height 动画
<div id="block1" class="block">
  This is block 1
</div>
<div id="block2" class="block">
  This is block 2
</div>
<div id="block3" class="block">
  This is block 3
</div>

<button type="button" onclick="removeBlock('block2');">
  Remove block 2
</button>

JS

function removeBlock(id) {
  var block = document.getElementById(id);
  block.classList.add('removedBlock');
}

当你删除时,由于opacity设置为0,元素消失,然后marginmax-height将使块崩溃。

请注意,由于无法触发转换 to/from 一个 auto 值,我为此设置了一个巨大的起始值 max-height。如果您想看到更平滑的过渡,请将 属性 更改为较低的值,或者简单地增加 transition 的持续时间。


更精致的版本可以在应用过渡之前获取元素的 height,例如

function removeBlock(id) {
  var block = document.getElementById(id);
  var blockHeight = block.offsetHeight;
  block.style.height =  blockHeight + 'px';
  block.classList.add('removedBlock');
}

所以样式变成了

.block {
  width: 200px;
  height: 20px;
  border: 1px solid black;
  margin: 20px 20px 0;
  transition: opacity 0s 0s, margin .5s 0s, height .5s 0s;
}

.removedBlock {
  box-sizing: border-box;
  opacity: 0;
  margin: 0;
  height: 0 !important;
}

JsFiddle

谢谢大家的回答!虽然它们都有些工作,但一旦布局变得更复杂,或者如果您尝试 hide/show more/other 个对象,它们就不会工作。

所以我在过去的几个小时里创建了一个 Javascript 解决方案,我认为它适用于任何情况(以及任何浏览器)。

简而言之,它的工作原理是,您可以使用 SetDisplay() 函数 "mark" 任意数量的元素 hidden/shown(请参阅第一个按钮)。完成后,您可以在不带任何参数的情况下调用相同的 SetDisplay 函数,然后看到奇迹发生了! Javascript 实际上会快速删除元素并让页面重排(所有这些对查看者都是不可见的)。然后它检查新位置,重新插入元素以隐藏并将所有其他元素移动到新位置,方法是设置 style.transition 并使用 position:relative 和新的 top 和 left 值。完成转换后,它会永久隐藏元素,重置所有已更改的样式值并让页面再次重排。

SetDisplay( "block2", "none" );
SetDisplay( "block3", "none" );
SetDisplay( "block4", "none" );
SetDisplay();

您可以用同样的方式重新插入元素(第二个按钮)。

SetDisplay( "block2", "" );
SetDisplay();

https://jsfiddle.net/yq7xor5j/3/

(编辑:对 fiddle 进行了更改以更正一个小错误)