在《深入淺出node》中看到了這個問題,感覺很有趣,那就寫一個吧!效果如圖:
我們先來實現一個簡單的氣泡排序:
const arrLength = 10
const arrRange = 30
const generateArr = () => {
return Array.from({ length: arrLength }).map(() =>
Math.floor(Math.random() * arrRange)
)
}
const compare = (x, y) => x - y
const swap = (a, i, j) => {
a[i] ^= a[j]
a[j] ^= a[i]
a[i] ^= a[j]
}
const bubbleSort = a => {
const len = a.length
for (let i = 0; i < len; i++) {
for (let j = 0; j < len - i - 1; j++) {
if (compare(a[j], a[j + 1]) > 0) {
swap(a, j, j + 1)
}
}
}
}
const arr = generateArr()
console.log(arr)
bubbleSort(arr)
console.log(arr)
複製程式碼
接下來實現一個圖表:
const generateChart = () => {
const block = document.querySelector('#sort')
block.style.width = `${arrLength * (pillarGap + pillarWidth)}px`
for (let i = 0; i < arrLength; i++) {
const newDiv = document.createElement('div')
Object.assign(newDiv.style, {
height: `${((arr[i] / arrRange) * 100).toFixed(0)}%`,
width: `${pillarWidth}px`,
marginLeft: `${pillarGap}px`
})
newDiv.innerText = arr[i]
block.append(newDiv)
}
}
複製程式碼
排序中主要變化是交換,再寫一個交換元素的函式:
function exchange(el1, el2) {
var ep1 = el1.parentNode,
ep2 = el2.parentNode,
index1 = Array.prototype.indexOf.call(ep1.children, el1),
index2 = Array.prototype.indexOf.call(ep2.children, el2)
ep2.insertBefore(el1, ep2.children[index2])
ep1.insertBefore(el2, ep1.children[index1])
}
複製程式碼
最後我們只要把 bubbleSort
變為非同步呼叫即可:
const bubbleSort = async a => {
const len = a.length
for (let i = 0; i < len; i++) {
for (let j = 0; j < len - i - 1; j++) {
await swapTransform(a, j, j + 1, compare(a[j], a[j + 1]) > 0)
}
}
return a
}
複製程式碼
全部程式碼在我的GitHub上: github.com/wen98y/work… 歡迎 Star
這個花了2個多小時寫完的,還是有些收穫:
- 多關注js原生操作DOM
- async 的運用
- css運算子優先順序
也有不足之處:這裡交換很生硬,沒有漸變的動畫,我想的是用transform來寫,但最後還是沒想出來,如果各位有高招,歡迎評論。
還有用原生js擼程式碼是真的爽!