作为一个后端开发程序员,我的手又伸到了前端了,这次是JS这一块,用原生JS实现冒泡排序的动态效果,先贴代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>冒泡排序</title>
<style>
.mainDiv{
text-align: center; /*让div内部文字居中*/
background-color: aliceblue;
border-radius: 20px;
width: 100%;
height: 100%;
margin: auto;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.sort_li {
display: flex;
align-items: flex-end;
border: 1px solid #ccc;
padding-left: 30%;
}
li {
margin-left: 10px;
/* height:200px; */
width: 50px;
list-style: none;
background-color: red;
position: relative;
}
li p {
position: absolute;
width: 50px;
text-align: center;
}
.completed {
background-color: bisque;
}
.bubbling {
background-color: green;
}
.form-group {
margin-bottom: 10px;
}
.num-input,.num-out {
width: 600px;
}
</style>
<script type="text/javascript" src="sort.js"></script>
</head>
<body>
<div class="mainDiv">
<div class="form-group">
<label for="arrLen">数组长度:</label>
<input name="arrLen" class="form-control" id="form-control" value='10' placeholder="请输入数组长度">
<input value='生成数组' id="createArr" onclick="initNum()" type="button">
</div>
<div class="form-group">
<label for="arr">排序前数组:</label><textarea name="arr" class="num-input" id="num-input" rows="3" readonly></textarea>
<label for="arr">排序后数组:</label><textarea name="arr" class="num-out" id="num-out" rows="3" readonly></textarea>
</div>
<div id="sort_ul">
<ul class="sort_li"></ul>
</div>
</div>
<script>
initNum();
</script>
</body>
</html>
function initNum() {
var numArr = [];
//获取排序数字的个数
var num = document.getElementById("form-control").value;
var numArray = document.getElementById("num-input");
numArr.length = 0;
numArray.value = '';
for (var i = 0; i < num; i++) {
numArr.push(randomGet(1, 50));
numArray.value = numArr;
}
var oUl = document.getElementsByClassName("sort_li")[0];
this.Arr = [];
init(numArr,oUl);
sort(numArr);
animation(oUl);
}
function init(numArr,oUl) {
let html = "";
numArr.map((item) => {
html += '<li class="" style="height: ' + item * 10 + 'px"><p>' + item + '</p></li>';
});
oUl.innerHTML = html;
}
function bubbleSortDom(arr, num, index, flag,oUl) {
let html = '',
i,
className = "";
for (i = 0; i < arr.length; i++) {
if (flag === true) {
className = "";
} else {
if (i == num + 1 || i == num) {
className = " bubbling";
} else if (i > index) {
className = "completed";
} else {
className = "";
}
}
html += '<li class="' + className + '" style="height: ' + arr[i] * 10 + 'px"><p>' + arr[i] + '</p></li>';
}
oUl.innerHTML = html;
document.getElementById("num-out").value = arr;
}
function animation(oUl) {
let Arr = this.Arr;
//清空
clearInterval(this.timer);
this.timer = setInterval(function(){
if (Arr.length > 0) {
this.bubbleSortDom(Arr[0][0], Arr[0][1], Arr[0][2], Arr[0][3],oUl);
Arr.shift();
} else {
clearInterval(this.timer);
}
}, 500);
}
function randomGet(a, b) {//产生一组随机数
var result = Math.random() * (b - a) + a;
return result >> 0;
}
// 冒泡排序算法实现
function sort(numArr) {
let resArr = numArr.slice(),
len = resArr.length,
temp,
sortOk;
for (let i = 0; i < len - 1; i++) {
sortOk = true;
for (let j = 0; j < len - i - 1; j++) {
temp = resArr[j];
if (resArr[j + 1] < resArr[j]) {
this.pushArr(resArr.slice(), j, len - 1 - i, false);
temp = resArr[j];
resArr[j] = resArr[j + 1];
resArr[j + 1] = temp;
sortOk = false;
}
this.pushArr(resArr.slice(), j, len - 1 - i, false);
}
if (sortOk == true) {
this.pushArr(resArr.slice(), -1, -1, true);
break;
}
}
}
function pushArr() {
this.Arr.push(Array.prototype.slice.call(arguments));
}
首先冒泡排序的算法不用多讲,这是一个合格的程序员必备的知识要点,主要说一下这次遇到的问题,
setInterval(),就是对这个方法不了解,导致多条线程同时启动并将生成的HTML渲染到同一个DOM节点,导致了页面闪烁(其实就是多条线程来回执行并渲染的结果),找了半天才发现是多线程的问题,最后解决的方法是在使用setInterval()之前用clearInterval(this.timer);来结束线程; (clearInterval() 方法可取消由 setInterval() 函数设定的定时执行操作;setInterval返回值相当于一个Id,每次执行都会产生一个特定的Id,返回值为数字,从一开始逐次累加。)