<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
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |