如何使div顺利移动?

时间:2020-12-08 11:30:20

I have a page where divs containing text appear one after one, and disappear as soon as they are followed by another, using CSS transition :

我有一个页面,其中包含文本的div一个接一个地出现,并且一旦它们被另一个跟随,则使用CSS转换消失:

on JSFiddle : https://jsfiddle.net/5kp6qdgg/9/

在JSFiddle:https://jsfiddle.net/5kp6qdgg/9/

HTML :

<body>
    Click multiple times on this button:
    <br />
    <input type="button" value="Display one more div" />
    <div id="div_container"></div>
</body>

CSS :

div#div_container {
  position: relative;
}

.log {
    position: relative;
    display: inline-block;
    margin-right: 50%;
    opacity: 1;
    -webkit-transition: all 2s;
    -moz-transition: all 2s;
    -ms-transition: all 2s;
    -o-transition: all 2s;
    transition: all 2s;
}

.hidden {
  opacity: 0;
}

Javascript :

// Event listener
var button = document.getElementsByTagName("input")[0];
button.addEventListener ('click', oneMore);

// Spawn a div
function oneMore() {
    var div = document.getElementById("div_container");
  div.innerHTML += "<div class=log>Hello, I will soon disappear</div>";
  clear ();
}

// Clear every div except the last
function clear () {
    var logs = document.getElementsByClassName("log");
    for (x=0; x<(logs.length-1); x++) {
        var classes = logs[x].className.split(" ");
        // Only thoses not already cleared
        if (classes.length == 1) {
            logs[x].className += (" waiting");
            (function (x) {
                window.setTimeout ( function () {
                    logs[x].className += (" hidden");
                    logs[x].addEventListener("transitionend", function () { logs[x].style.display = "none" });
                    logs[x].addEventListener("webkitTransitionend", function () { logs[x].style.display = "none" });
                }, 500);
            })(x);
        }
    }
}

So the remaining div move up to the top, but jerkily, whereas I would like it to translate smoothly.

所以剩下的div会上升到顶部,但是我会希望它顺利翻译。

Does anyone knows how to do this only with CSS and pure javascript ?

有谁知道如何使用CSS和纯JavaScript进行此操作?

1 个解决方案

#1


0  

If you are able to change the display to block you can transition the height,margin, and padding so that they hide without taking up space. Then you do not need to do the ending display:none which is what is causing the sudden jerk.

如果您能够将显示更改为阻止,则可以转换高度,边距和填充,以便在不占用空间的情况下隐藏它们。然后你不需要做结束显示:none是导致突然混蛋的原因。

Also you used .innerHTML+= this is inefficient and will cause all the elements to be recreated and rendered, and also makes it so you have to keep adding back the classes in clear.

你也使用过.innerHTML + =这是低效的,会导致所有元素被重新创建和渲染,并且还使得你必须继续以明确的方式添加类。

Instead you could create an actual element, set all the appropriate attributes (class, innerText, etc) then appendChild it. This way you can keep the classes and event listeners you may want to put on them without having to continually re-add them.

相反,你可以创建一个实际的元素,设置所有适当的属性(类,innerText等)然后appendChild它。这样,您可以保留您可能希望在其上放置的类和事件侦听器,而无需不断地重新添加它们。

// Event listener
var button = document.getElementsByTagName("input")[0];
button.addEventListener ('click', oneMore);

// Spawn a div
function oneMore() {
  var div = document.getElementById("div_container");
  var newDiv = document.createElement("div");
  newDiv.classList.add("log");
  newDiv.innerText = "Hello, I will soon disappear";
  div.appendChild(newDiv);
  if(newDiv.previousElementSibling){
    newDiv.previousElementSibling.classList.add("hidden");
  }
}
div#div_container {
  position: relative;
}

.log {
    position: relative;
    display: block;
    white-space: nowrap;
    margin: 5px;
    margin-right: 50%;
    padding: 1px 10px;
    border-radius: 20px;
    opacity: 1;
    background: rgba(250,0,0,0.7);
    color: #fff;
    width:190px;
    height:20px;
    -webkit-transition: all 2s;
    -moz-transition: all 2s;
    -ms-transition: all 2s;
    -o-transition: all 2s;
    transition: all 2s;
}

.hidden {
  opacity: 0;
  height:0px;
  margin-top:0px;
  margin-bottom:0px;
  padding-top:0px;
  padding-bottom:0px;
}
Click multiple times on this button:
<br />
<input type="button" value="Display one more div" />
<div id="div_container"></div>

It's a bit harder to hide an inline-block as even if you 0 out all the other style properties like height, margin, padding, etc the element is still going to effect the position of the other elements until display is set to none. You could do some tricks like setting display to block right before hiding it and then transitioning the previously mentioned styles, but that may again affect the positions of the other elements. Meaning when the display is set to block it will push the following elements down before transitioning.

隐藏内联块有点困难,因为即使你输出所有其他样式属性,如高度,边距,填充等,元素仍然会影响其他元素的位置,直到显示设置为无。您可以做一些技巧,例如在隐藏它之前将显示设置为阻止,然后转换前面提到的样式,但这可能会再次影响其他元素的位置。显示设置为阻止时的含义,它将在转换之前将以下元素向下推。

There are other tricks you could use but they would require extra work and may affect the way you want your layout to be.

您可以使用其他技巧,但它们需要额外的工作,并可能影响您希望布局的方式。

#1


0  

If you are able to change the display to block you can transition the height,margin, and padding so that they hide without taking up space. Then you do not need to do the ending display:none which is what is causing the sudden jerk.

如果您能够将显示更改为阻止,则可以转换高度,边距和填充,以便在不占用空间的情况下隐藏它们。然后你不需要做结束显示:none是导致突然混蛋的原因。

Also you used .innerHTML+= this is inefficient and will cause all the elements to be recreated and rendered, and also makes it so you have to keep adding back the classes in clear.

你也使用过.innerHTML + =这是低效的,会导致所有元素被重新创建和渲染,并且还使得你必须继续以明确的方式添加类。

Instead you could create an actual element, set all the appropriate attributes (class, innerText, etc) then appendChild it. This way you can keep the classes and event listeners you may want to put on them without having to continually re-add them.

相反,你可以创建一个实际的元素,设置所有适当的属性(类,innerText等)然后appendChild它。这样,您可以保留您可能希望在其上放置的类和事件侦听器,而无需不断地重新添加它们。

// Event listener
var button = document.getElementsByTagName("input")[0];
button.addEventListener ('click', oneMore);

// Spawn a div
function oneMore() {
  var div = document.getElementById("div_container");
  var newDiv = document.createElement("div");
  newDiv.classList.add("log");
  newDiv.innerText = "Hello, I will soon disappear";
  div.appendChild(newDiv);
  if(newDiv.previousElementSibling){
    newDiv.previousElementSibling.classList.add("hidden");
  }
}
div#div_container {
  position: relative;
}

.log {
    position: relative;
    display: block;
    white-space: nowrap;
    margin: 5px;
    margin-right: 50%;
    padding: 1px 10px;
    border-radius: 20px;
    opacity: 1;
    background: rgba(250,0,0,0.7);
    color: #fff;
    width:190px;
    height:20px;
    -webkit-transition: all 2s;
    -moz-transition: all 2s;
    -ms-transition: all 2s;
    -o-transition: all 2s;
    transition: all 2s;
}

.hidden {
  opacity: 0;
  height:0px;
  margin-top:0px;
  margin-bottom:0px;
  padding-top:0px;
  padding-bottom:0px;
}
Click multiple times on this button:
<br />
<input type="button" value="Display one more div" />
<div id="div_container"></div>

It's a bit harder to hide an inline-block as even if you 0 out all the other style properties like height, margin, padding, etc the element is still going to effect the position of the other elements until display is set to none. You could do some tricks like setting display to block right before hiding it and then transitioning the previously mentioned styles, but that may again affect the positions of the other elements. Meaning when the display is set to block it will push the following elements down before transitioning.

隐藏内联块有点困难,因为即使你输出所有其他样式属性,如高度,边距,填充等,元素仍然会影响其他元素的位置,直到显示设置为无。您可以做一些技巧,例如在隐藏它之前将显示设置为阻止,然后转换前面提到的样式,但这可能会再次影响其他元素的位置。显示设置为阻止时的含义,它将在转换之前将以下元素向下推。

There are other tricks you could use but they would require extra work and may affect the way you want your layout to be.

您可以使用其他技巧,但它们需要额外的工作,并可能影响您希望布局的方式。