【前端】可视化之冒泡排序

  • 实现思路

使用js移动元素位置,利用css的transition属性实现过渡动画。在线体验

创建一个数组arr,数组的每一项保存着节点元素的文本值(innerText)和元素在节点列表中的索引nodeIndex, 因为接下来的并不是真的交换两个节点,而是交换两个节点的位置(可能有点不好理解)。

function init() {
  let fragment = document.createDocumentFragment();
  for (let i = 0; i < 10; i++) {
    let div = document.createElement('div'),
      num = parseInt(Math.random() * 10);
    arr.push({
      val: num,
      nodeIndex: i, //这里保存的是节点在nodeList中的位置
    });
    
    //
    
  }
}

举例说明:

在页面中,从左往右肉眼观测到的元素位置是这样的(order表示从左往右的顺序)

order012
nodeIndex012
val321

3 > 2, swap(3, 2)

在经过第一次交换之后,元素的位置变成了:

order012
nodeIndex102
val231

所以,接下来要交换位置的节点是 (0, 2) 而不是 (1, 2)。

完整代码如下:


<script>
  let nodeList = document.getElementsByClassName('num'),
    reloadBtn = document.querySelector('.reload'),
    sortBtn =  document.querySelector('.sort');
  let initColor = 'rgb(173, 216, 230)', activeColor = 'rgb(0, 128, 0)', sortedColor = 'rgb(255, 165, 0)';
  let showConsoleNode = document.querySelector('.showConsole');
  let arr = [], timeout = 1;

  function handleChange() {
    let selectOps = document.querySelector('#speed-control');
    // console.log(selectOps)
    let selectIdx = selectOps.selectedIndex;
    let val = selectOps.options[selectIdx].value;
    timeout = Number(val);
    console.log(timeout)
  }

  function swapPosition(node1, node2) {
    [node1.style.left, node2.style.left] = [node2.style.left, node1.style.left];
  }

  function setBgColor(nodeArr, color) {
    for (let i = 0; i < nodeArr.length; i++) {
      nodeArr[i].style.background = color;
    }
  }

  function resetColor(node1, node2, lastIndex) {
    setTimeout(() => {
      // console.log(node1.style.left);
      if (Number(node1.style.left.replace('px', '')) === lastIndex * 50) {
        setBgColor([node2], initColor);
        setBgColor([node1], sortedColor)
      } else {
        setBgColor([node1, node2], initColor)
      }
    }, timeout * 0.7 * 1000);
  }

  function swap(arr, i, j) {
    [arr[i], arr[j]] = [arr[j], arr[i]];
  }
  function bubbleSort(arr) {
    let len = arr.length, cnt = 0;
    sortBtn.disabled = reloadBtn.disabled = true;
    for (let i = 0; i < len - 1; i++) {
      for (let j = 0; j < len - i - 1; j++) {
        let node1 = nodeList[arr[j].nodeIndex],
          node2 = nodeList[arr[j + 1].nodeIndex];
        cnt++;
        let val1 = arr[j].val, val2 = arr[j + 1].val;
        if (val1 > val2) {
          setTimeout(() => {
            resetColor(node1, node2, len - i - 1);
            setBgColor([node1, node2], activeColor);
            setTimeout(() => {
              swapPosition(node1, node2);
            }, timeout * 0.6 * 1000);
            showConsoleNode.innerText =
              `compare ${val1} with ${val2}\n${val1} > ${val2}, swap(${val1}, ${val2})`;
          }, cnt * timeout * 1.6 * 1000);
          swap(arr, j, j + 1);
        } else {
          setTimeout(() => {
            setBgColor([node1, node2], activeColor);
            showConsoleNode.innerText =
              `compare ${val1} with ${val2}`;
            resetColor(node2, node1, len - i - 1);
          }, cnt * timeout * 1.6 * 1000);
        }
      }
    }
    setTimeout(() => {
      showConsoleNode.innerText = null;
      sortBtn.disabled = reloadBtn.disabled = false;
      setBgColor(nodeList, initColor)
    }, cnt * timeout * 1.6 * 1000 + timeout * 1.6 * 1000);
  }

  function init() {
    let fragment = document.createDocumentFragment();
    for (let i = 0; i < 10; i++) {
      let div = document.createElement('div'),
        num = parseInt(Math.random() * 10 + 1);
      arr.push({
        val: num,
        nodeIndex: i, //这里保存的是节点在nodeList中的位置
      });
      div.className = 'num';
      div.style.height = `${num * 20}px`;
      div.style.left = `${i * 50}px`;
      div.style.bottom = '0';
      div.style.background = initColor;
      div.style.transition = `left ${timeout}s, background ${timeout * 0.6}s`;
      div.innerText = num;
      fragment.append(div);
    }
    document.querySelector('.animate-contanier').append(fragment);
  }

  function reload() {
    arr = [];
    for (let i = 0; i < 10; i++) {
      let div = nodeList[i],
        num = parseInt(Math.random() * 10 + 1);
      arr.push({
        val: num,
        nodeIndex: i,
      });
      div.style.left = `${i * 50}px`;
      div.style.bottom = '0';
      div.style.height = `${num * 20}px`;
      div.innerText = num;
    }
  }

  init();
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值