Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
    <title>Animation Test</title>
    <style>
        .list {
            display: flex;
        }
        .list div {
            width: 32px;
            height: 32px;
            text-align: center;
            font-size: 16pt;
            border-radius: 15px;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 6px;
            cursor: pointer;
            background-color: #eee;
            user-select: none;
        }
        .list div.hit {
            animation: fade 1.5s ease-out;
        }
        @keyframes fade {
            from {
                background-color: blueviolet;
            }
            to {
                background-color: #ddf;
            }
        }
        button {
            margin: 12px;
            width: 100px;
        }
    </style>
</head>
<body>
    <div class="list">
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
    </div>
    <button id="b">Play</button>
    <input type="range" id="r" min="50" max="1000" value="450">
    <script>
        document.querySelector('.list').addEventListener('click',
            function (e) {
                // 聽 .list click 事件再由 e.target 判斷是不是 div
                // 相當於 $('.list').on('click', 'div', function(e) { ... });
                const t = e.target;
                if (t.tagName === 'DIV') {
                    // 移除 hit class 再加回去,若仍在播放動畫可停止現有動畫,觸發重新播放
                    console.log('remove');
                    t.classList.remove('hit');
                    // 這裡用 setTimeout 或 requestAnimationFrame 再加回 hit class
                    // 如果直接加回去,不會播放動畫
                    // requestAnimationFrame 比 setTimeout 好,會抓準在下次繪製時執行
                    // 不像 setTimeout 自己抓時間可能過長或過短
                    requestAnimationFrame(function () {
                        t.classList.add('hit');
                        // 動畫播放完後移除 hit class,這裡利用 animationend 事件
                        t.addEventListener('animationend', function () {
                            t.classList.remove('hit');
                        }, { // addEventListener 第三個參數可以設定 options, once 表示只執行一次
                            once: true
                        });
                    });
                }
            });
        // 按鈕自動播放
        let running = false;
        document.getElementById('b').addEventListener('click', (e) => {
            running = !running; // 切換播放狀態
            e.target.textContent = running ? 'Stop' : 'Play';
            if (running) play();
        });
        // 取得 .list div 陣列
        // querySelectorAll 回傳的是 NodeList,不是 Array
        // 這裡用 [...NodeList] 展開成 Array
        let divs = [...document.querySelectorAll('.list div')];
        function play() {
            // 隨機點擊一個 div
            let i = Math.floor(Math.random() * divs.length);
            divs[i].click();
            // 如果還在播放,就隨機時間後點擊一個 div,隨機長度範圍由 input range 決定
            if (running) 
                setTimeout(play, Math.random() * document.getElementById('r').value);
        }
    </script>
</body>
</html>
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
darkthreadpro
0viewers