前言#
今天做了一个小的 js 题目,感觉还是涉及到很多知识点,这篇文章整理遇到的问题。
题目#
题目分成两个部分,第一个部分很简单,就是写一个队列的可视化,支持左进右进,左出又出,做出来的效果大概如下图:

具体代码查看第一部分 ↗。
第二部分是让这个队列可视化,数字变为生成元素的高,限制数字在 10-100,元素上限 60,给队列添加一个排序功能。 题目不是很复杂,不过在实现的过程中还是遇到了一些小问题,主要是基础问题,整理总结一下。
元素的添加和移除#
对队列的操作就是对元素的添加和移除,我们可以用两个函数来实现这个功能,两个函数都需要有一个方向的参数,确定我们的元素是从队列的那一端添加活删除,虽然我们已经通过元素的高度来展示我们的元素大小,但是为了更直观还是要在元素上添加一个文本节点来展示元素的大小。另外为了后面的排序功能,我们要给我们的元素按先后顺序编号,显示在元素下方,这样我们排序后就能够知道元素是第几个添加的。效果如下:

如果我们直接用输入的值设置高度当元素差距特别小的时候可能不是很直观,所以我们可以设置一个系数来设置高度。 添加和删除元素就用 removeChild 和 appendChild 两个方法很容易就实现了。
元素编号的重置#
在我们删除元素的时候,我们会遇到元素编号的断裂,比如这种情况:

如果我们此时用左侧出来删除5号元素,那么元素的编号就会变成 1,2,3,4,6,当元素比较多我们多次操作,元素的编号就非常混乱了,所以我们在删除元素的时候要注意重置一下元素的编号,逻辑非常简单,我们只要找到比当前删除元素编号大的元素,把他们的编号值减去1就可以了。但是这里比较两个文本节点的 nodeValue 的时候会出现一个小问题,js的数据类型是动态的,所以我们在进行关系操作符运算的时候会自动帮我们转换类型,我们也经常不关注关系操作符运算的具体细节,在这里就会出现问题,因为比较的两个值都是 string 类型,他们在比较的时候不会转成数值进行比较,而是比较两个字符串对应的字符的 ASCII 码值,比如我们比较 "1" 和 "11", 这两个字符串的值是相等的,因为 11 的第一位和 1 的 ASCII码值是相等,所以我们在比较的时候需要把字符串转为数值来进行比较。
元素排序#
最后要做的功能就是元素排序了,我们可以使用任意的排序算法,我用冒泡和快速排序都做了一遍,做出排序的可视化也可以让我们直观地看到不同排序方法的执行过程,帮助我们理解各种排序算法。这个功能有两点要实现,一个是两个元素的交换,另一个是排序的每一步设置一个时间间隔,方便我们看清楚排序过程。
两个元素的交换#
实现两个元素的交换我没有想到特别好的方法,就直接用 cloneNode(true) 来替换原先的元素的取巧的方法,我不知道这个方法性能如何,或者有更好的方法,限于目前自己知道的知识没想到特别好的方法。注意的是 cloneNode 的参数如果设置 true 是同时克隆子元素,一般我们需要的。
设置sleep#
为了方便我们更清楚的看到排序的过程,我们给每一步排序设置一个时间间隔,也就是实现一个sleep函数,用Promis和await来实现
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}javascript排序的效果如下(冒泡排序):

具体代码查看第二部分 ↗
总结#
一个很小的问题,不过在实现的过程中还是遇到一些小问题,js是一个简单而又复杂的语言,一些语言的基础概念要掌握的比较仔细,理解好这门语言才能用好这个工具。