js+css模拟接收websocket推送数据,实现冒泡置顶动画效果
效果如下:
1.第一种方法
思路: 1).在外面定义一个假的浮动盒子,当数据变化时,将原来的数据节点删除, 2).将变化的数据放到这个盒子里,移动盒子位置到顶部 3).盒子移动到顶部之后,隐藏该盒子,将变化之后的数据节点插入到第一条的位置
<!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 () { // 模拟接收到新数据
document.getElementsByClassName('hide-box')[0].classList.add('show')
document.getElementsByTagName('p')[9].remove();
setTimeout(function () { // 假数据缓慢移动到最顶部
document.getElementsByClassName('hide-box')[0].style.top = '0'
setTimeout(function () { // 隐藏假数据
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'
// 插入真数据
document.getElementById('box').insertBefore(newElement, document.getElementsByTagName('p')[0])
}, 2000)
}, 200)
}, 2000)
</script>
第二种方法(推荐)
思路: 1).将盒子里面的子元素都绝对定位,每一个添加不同的top值 2).将变化的元素节点,插入到第一条位置 3).遍历循环所有的子元素,重新添加top值 4).循环的时候,判断一下移动元素,给它添加一个高点的z-index层级,这样移动的时候,就可以从其他元素上面飘过
<!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>
// 填充元素
for (var i = 0; i < 100; i++) {
document.getElementById('box').innerHTML += '<p id="list' + i + '" style = "top:' + (i * 30) + 'px">' + i + '</p>'
}
// 模拟websocket接收数据
clearInterval(timer);
var timer = setInterval(function () {
changeList('box', 'list' + Math.floor(Math.random() * 100))
}, 2000)
// 接收更改数据
function changeList(parentId, errorId) {
// 获取全部子元素
var parentEle = document.getElementById(parentId);
// 获取全部子元素
var allChild = parentEle.children;
// 获取将要移动的元素节点
var errorIdEle = document.getElementById(errorId);
errorIdEle.innerHTML = '<p class="red">' + errorId + '-' + new Date().getTime() + '</p>'
errorIdEle.style.zIndex = 2;
// 获取第一个子元素
// var firstChildELe = document.getElementById(document.getElementById(parentId).firstElementChild.id);
parentEle.insertBefore(errorIdEle, allChild[0]);
clearTimeout(timer2)
var timer2 = setTimeout(function () {
init(parentId, errorId);
}, 500)
}
// 初始化列表,更改元素顺序,重置层级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>