js+css simulates receiving the data pushed by websocket to achieve the animation effect of bubbling to the top

Keywords: Front-end

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>

Posted by saandel on Fri, 15 May 2020 08:23:28 -0700