js+css simulates receiving the data pushed by websocket to achieve the animation effect of bubbling to the top
The effect is as follows:
1. The first method
Ideas: 1) . define a fake floating box outside. When the data changes, delete the original data node, 2) . put the changed data in this box and move the box to the top 3) . after the box moves to the top, hide the box and insert the changed data node into the first one
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> * { margin: 0; padding: 0; } html, body { display: flex; height: 100%; width: 100%; justify-content: center; align-items: center; } .box { height: 320px; width: 400px; background: #333; overflow: auto; position: relative; } .box p { height: 30px; line-height: 30px; background: #00ACED; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; } .box .hide-box { transform: scale(0); height: 30px; width: 100%; background: red; position: absolute; top: 90%; left: 0; transition: top 2s ease; } .box .hide-box.show { transform: scale(1); } .box .red { background: red; } </style> </head> <body> <div id="box" class="box"></div> </body> </html> <script> for (var i = 0; i < 100; i++) { document.getElementById('box').innerHTML += '<p>' + i + '</p>' } document.getElementById('box').innerHTML += '<p class="hide-box">9</p>' setTimeout(function () { // Analog receives new data document.getElementsByClassName('hide-box')[0].classList.add('show') document.getElementsByTagName('p')[9].remove(); setTimeout(function () { // Fake data moves slowly to the top document.getElementsByClassName('hide-box')[0].style.top = '0' setTimeout(function () { // Hide fake data document.getElementsByClassName('hide-box')[0].classList.remove('show') document.getElementsByClassName('hide-box')[0].style.top = '90%' var newElement = document.createElement('p') newElement.classList.add('red') newElement.innerHTML = '9' // Insert true data document.getElementById('box').insertBefore(newElement, document.getElementsByTagName('p')[0]) }, 2000) }, 200) }, 2000) </script>
Second method (recommended)
Ideas: 1) . absolutely locate the sub elements in the box, and add different top values for each 2) . insert the changed element node into the first position 3) . loop through all sub elements and add top value again 4) . when cycling, judge the moving element, add a high z-index level to it, so that when moving, it can float over other elements
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> * { margin: 0; padding: 0; } html, body { display: flex; height: 100%; width: 100%; justify-content: center; align-items: center; } .box { height: 320px; width: 400px; background: #333; overflow: auto; position: relative; } .box p { position: absolute; left: 0; top: 0; z-index: 1; width: 100%; height: 30px; line-height: 30px; background: #00ACED; border-top: 1px solid #ccc; border-bottom: 1px solid #ccc; transition: top 1.2s ease; } .box .red { background: red; } </style> </head> <body> <div id="box" class="box"></div> </body> </html> <script> // Fill element for (var i = 0; i < 100; i++) { document.getElementById('box').innerHTML += '<p id="list' + i + '" style = "top:' + (i * 30) + 'px">' + i + '</p>' } // Simulate websocket receiving data clearInterval(timer); var timer = setInterval(function () { changeList('box', 'list' + Math.floor(Math.random() * 100)) }, 2000) // Receive change data function changeList(parentId, errorId) { // Get all child elements var parentEle = document.getElementById(parentId); // Get all child elements var allChild = parentEle.children; // Get the element node to be moved var errorIdEle = document.getElementById(errorId); errorIdEle.innerHTML = '<p class="red">' + errorId + '-' + new Date().getTime() + '</p>' errorIdEle.style.zIndex = 2; // Get the first child element // var firstChildELe = document.getElementById(document.getElementById(parentId).firstElementChild.id); parentEle.insertBefore(errorIdEle, allChild[0]); clearTimeout(timer2) var timer2 = setTimeout(function () { init(parentId, errorId); }, 500) } // Initialize list, change element order, reset level z-index function init(parentId, errorId) { var allChild = document.getElementById(parentId).childNodes; for (var i = 0, len = allChild.length; i < len; i++) { var item = allChild[i]; item.style.top = (i * 30) + 'px' if (item.id !== errorId) { item.style.zIndex = 1 } } } </script>