原生js如何实现DOM节点冒泡排序的可视化?

比方说下图中,点击升序或者降序会对蓝色的li元素进行排序图片描述

我的实现升序的代码如下:

for(var i = 0; i < lis.length -1 ; i++){
    for(var j = 0; j < lis.length - i - 1; j++){
        if(lis[j].style.height > lis[j+1].style.height){
            ul.insertBefore(lis[j+1],lis[j]);
        }
    }
}

可点击后的效果是干蹦,不是动画过渡的。请问如何在不依赖任何库和框架的情况下,实现冒泡排序的可视化呢?

阅读 4.1k
2 个回答

我参照了知乎大神的方法,自己花了大半天的时间整出来了。代码有点乱,不过我写了注释,将就看吧。
(ase是一个按钮,我添加了点击事件。)

ase.onclick = function(){
   var lis = ul.getElementsByTagName('li');
   //设置一个arr数组,用来存放每个li的高度
   var arr = [];
   for(var i = 0; i < lis.length; i++){
       arr.push(lis[i].style.height);
   }
   //对所有的li的高度值进行冒泡升序排列
   sort(arr);
   //定义一个全局变量timer定时器
   timer = setInterval(render,500);
}
//state数组,存放每一次比较的结果
var state = [];
//冒泡计数器,存放比较的总次数
var count1 = 0;
//冒泡排序(升序),将第i趟的第arr.length - i - 1次的比较结果都存放到state数组中
function sort(arr){
    for(var i = 0; i < arr.length -1 ; i++){
        for(var j = 0; j < arr.length - i - 1; j++){
            if(arr[j] > arr[j+1]){
               var temp = arr[j+1];
               arr[j+1] = arr[j];
               arr[j] = temp;
               count1++;
               state.push(arr.slice(0));
            }
        }
    }
}
//渲染计数器,初始值为0
var count2 = 0;
//将每一趟中的每一次比较都渲染到页面中
function render(){
    var lis = ul.getElementsByTagName('li');
    var s = state.shift() || [];
    //循环遍历li元素,给每一个li的高度分别设置为第i次比较后每一项的值
    for(var i = 0; i < lis.length; i++){
        lis[i].style.height = s[i];
    }
    //渲染计数器,每次渲染就加一
    count2++;
    if(count2 == count1){
        clearInterval(timer);
    }
}

1.循环全部改成if判断,判断一次更新一次dom
2.for循环中创建一个动画队列,循环结束再复现出来

只想到这两个方案。感觉第二个更好,因为实现这一个就可以实现其他的排序算法的可视化

当时做ife的时候用的第一个

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题