效果图
HTML代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#div-queue>div {
width: 10px;
background-color: red;
float: left;
margin: 0px 5px 0 0;
}
#div-queue::after {
width: 0;
height: 0;
content: '';
display: block;
clear: both;
}
#div-queue {
border: black 1px solid;
height: 300px;
margin: 20px 0 0 0;
display: flex;
align-items: flex-end;
}
button {
cursor: pointer;
}
</style>
</head>
<body>
<label id="widget">
<input type="text" id="input-data">
<button type="button" id="btn-left-push">左侧入</button>
<button type="button" id="btn-right-push">右侧入</button>
<button type="button" id="btn-left-pop">左侧出</button>
<button type="button" id="btn-right-pop">右侧出</button>
<button type="button" id="btn-sort">排序</button>
<button type="button" id="btn-random">随机50</button>
interval(ms):<input type="text" id="input-interval" value="10" />
</label>
<div id="div-queue">
</div>
<script src="task.js"></script>
</body>
</html>
JS代码
var data = [];
var $ = function (id) {
return document.getElementById(id);
}
$('widget').addEventListener('click', e => {
let input = Number($('input-data').value.trim());
switch (e.target.id) {
case "btn-left-push":
if (!checkInput(input)) break;
if (data.length > 50) {
alert('队列已满,无法继续添加数据!')
break;
}
data.unshift(input);
$('input-data').value = '';
render();
break;
case "btn-right-push":
if (!checkInput(input)) break;
if (data.length > 50) {
alert('队列已满,无法继续添加数据!')
break;
}
data.push(input);
$('input-data').value = '';
render();
break;
case "btn-left-pop":
if (data.length == 0) {
alert('队列为空,无法弹出数据!');
break;
}
alert(data.shift());
render();
break;
case "btn-right-pop":
if (data.length == 0) {
alert('队列为空,无法弹出数据!');
break;
}
alert(data.pop());
render();
break;
case "btn-sort":
let i = data.length - 1,
j = 1,
timer = null;
let inerval = $('input-interval').value;
timer = setInterval(() => {
if (i >= 0) {
if (j <= i) {
let element1 = $(`${j - 1}`);
let element2 = $(`${j}`);
element1.style.background = 'green';
element2.style.background = 'green';
setTimeout(() => {
element1.style.background = 'red';
element2.style.background = 'red';
}, Number($('input-interval').value) * 2);
if (data[j - 1] > data[j]) {
[data[j], data[j - 1]] = [data[j - 1], data[j]];
render(j - 1, j);
}
j++;
} else {
i--;
j = 1;
}
} else {
clearInterval(timer);
}
}, inerval);
break;
case "btn-random":
for (let i = 0; i < 50; i++) {
data[i] = Math.round(Math.random() * 90 + 10);
}
render();
break;
}
});
function render(...arr) {
if (arr.length != 0) {
let element1 = $(`${ arr[0] }`);
let element2 = $(`${ arr[1] }`);
element1.style.background = 'blue';
element2.style.background = 'blue';
setTimeout(() => {
element1.style.background = 'red';
element2.style.background = 'red';
}, Number($('input-interval').value) * 2);
transform(element1, 'height', data[arr[0]] * 2, (Number($('input-interval').value) / 2) - 5, 5);
transform(element2, 'height', data[arr[1]] * 2, (Number($('input-interval').value) / 2) - 5, 5);
} else {
let content = '';
for (let i = 0; i < data.length; i++) {
content += `<div id="${ i }", style="height:${ data[i] * 2 }px;"></div>`
}
$('div-queue').innerHTML = content;
}
}
function checkInput(input) {
if (isNaN(input) || input < 10 || input > 100) {
alert('输入的数据不合法,请重新输入!');
$('input-data').value = '';
return false;
}
return true;
}
function transform(obj, attr, targetStatus, interval, speed, callback = () => {}) {
if (obj.animation == undefined) obj.animation = {};
if (obj.animation[attr] == undefined) {
obj.animation[attr] = {};
obj.animation[attr].target = targetStatus;
obj.animation[attr].timer = setInterval(() => {
let currentValue = parseInt(getComputedStyle(obj)[attr]);
if (speed > 0 && currentValue > targetStatus) speed = -speed;
let newValue = currentValue + speed;
if ((speed < 0 && newValue < targetStatus) || (speed > 0 && newValue > targetStatus)) {
newValue = targetStatus;
}
obj.style[attr] = newValue + 'px';
if (currentValue === targetStatus) {
clearInterval(obj.animation[attr].timer);
delete obj.animation[attr];
callback();
}
}, interval)
} else {
if (targetStatus != obj.animation[attr].target) {
let tempTimer = setInterval(() => {
if (!(attr in obj.animation)) {
transform(obj, attr, targetStatus, interval, speed, callback);
clearInterval(tempTimer);
tempTimer = null;
}
}, 10);
}
}
}