实时视觉插入排序有间隙,输出有延迟

好吧,我对 JS 比较陌生,但在 python 和 java 方面有丰富的经验。

我的代码有两个问题需要帮助。首先这是我的代码的解释和背景。

理想情况下,我想要最简单的结构化视觉排序程序,我可以将其用作我的编码进程的基础以供参考。我首先最大化一个容器 div,它用于填充 x 数量的 div .bars,div 的宽度和位置在插入时由 Flexbox 自动处理。每个添加的 div 的高度是随机生成的,并存储在每个单独的元素属性中。我已经完成了所有这些,很简单。然后我创建了一个元素交换器函数,可以交换 DOM 中的元素位置,效果非常好。现在回答我的问题。我希望看到元素在 for 循环迭代时实时排序,但直到循环结束它们才会更新。我找不到任何错误的插入算法也无法正常工作,但我不认为我的工作方法是错误的。任何帮助将不胜感激。对于其他人来说应该非常容易弄清楚。

const sortDisplay = document.getElementById('sortDisplay');

let resetbtn = document.querySelector('.reset');

resetbtn.addEventListener('click', reset);


let count = 0;

let amount = 100;


// create div that has custom attribute value, unique style tag, default bar style and append.

function generateBar() {

  // generate div

  let bar = document.createElement('div');

  // keep track of the total amount of bars

  count++;

  // assign random number 0-100 and setAttribute to the div

  let temp = Math.floor(Math.random() * 101);

  // create custom attribute that holds its value

  bar.setAttribute('value', temp);

  // create unique style tag with height as a percentage based on Attribute

  let barHeight = document.createElement('style');

  barHeight.innerHTML = `.barHeight${count} {height: ${temp}%;}`;

  // add that unique style to the DOM

  sortDisplay.appendChild(barHeight);

  // now add that unique style to the div

  bar.classList.add(`barHeight${count}`);

  // use standard style from css as well

  bar.classList.add('sortBar');

  // now add that div to the DOM

  sortDisplay.appendChild(bar);

}


// clear container div and regenerate

function reset() {

  // clear all data within the container

  sortDisplay.innerHTML = '';

  // reset the count

  count = 0;

  // generate k bars

  for (let i = 0; i < amount; i++) {

    generateBar();

  }

}


qq_遁去的一_1
浏览 52回答 1
1回答

GCT1015

这个错误非常小:您正在比较字符串,而不是排序中的数字。添加数字转换:if (+document.querySelectorAll('.sortBar')[j].getAttribute('value') < +document.querySelectorAll('.sortBar')[j-1].getAttribute('value')) {作为字符串,例如"3" > "29".可视化不是“实时可见”,因为代码完成得非常快,而且也没有释放控制并等待 DOM 重新渲染。强制 DOM 重新渲染存在一些小问题,但我认为这在这里并不重要。要解决此问题,请在循环中添加延迟,这非常简单,您所需要的只是一个规范的延迟函数 (&nbsp;const delay = ms => new Promise(res => setTimeout(res, ms));),在( )async前面,以及交换之间的适当延迟 (&nbsp;,目前为 25 毫秒。确切的时间是不能保证,由于多种因素,例如一次可能需要 22 毫秒,下次需要 27 毫秒,但这并不是太重要)。sortasync function sortawait delay(DELAY_BETWEEN_SWAPS);然而,这会导致取消问题:现在可以在排序仍在进行的情况下进行重置(异步性的困境)。因此,需要检查当前的排序是否被取消。因此,每个排序过程都需要一个取消令牌,当按下重置时,可以使用该取消令牌来停止旧的排序。最后但最重要的是,开始新的排序(只需按“按钮”),也会自动取消最后的排序。请注意,我展示的是一些概念,但不一定是能够赢得美容奖的代码。我也不会改变任何“有效但我不会那样做”的东西——例如,我更喜欢画布而不是用大量的 DOM 更新来做动画。工作版本:const sortDisplay = document.getElementById('sortDisplay');let resetbtn = document.querySelector('.reset');resetbtn.addEventListener('click', reset);const DELAY_BETWEEN_SWAPS = 25;const delay = ms => new Promise(res => setTimeout(res, ms));let cancelLast = () => {};let count = 0;let amount = 100;// create div that has custom attribute value, unique style tag, default bar style and append.function generateBar() {&nbsp; // generate div&nbsp; let bar = document.createElement('div');&nbsp; // keep track of the total amount of bars&nbsp; count++;&nbsp; // assign random number 0-100 and setAttribute to the div&nbsp; let temp = Math.floor(Math.random() * 101);&nbsp; // create custom attribute that holds its value&nbsp; bar.setAttribute('value', temp);&nbsp; // create unique style tag with height as a percentage based on Attribute&nbsp; let barHeight = document.createElement('style');&nbsp; barHeight.innerHTML = `.barHeight${count} {height: ${temp}%;}`;&nbsp; // add that unique style to the DOM&nbsp; sortDisplay.appendChild(barHeight);&nbsp; // now add that unique style to the div&nbsp; bar.classList.add(`barHeight${count}`);&nbsp; // use standard style from css as well&nbsp; bar.classList.add('sortBar');&nbsp; // now add that div to the DOM&nbsp; sortDisplay.appendChild(bar);}// clear container div and regeneratefunction reset() {&nbsp; cancelLast();&nbsp; // clear all data within the container&nbsp; sortDisplay.innerHTML = '';&nbsp; // reset the count&nbsp; count = 0;&nbsp; // generate k bars&nbsp; for (let i = 0; i < amount; i++) {&nbsp; &nbsp; generateBar();&nbsp; }}// when page is loaded resetreset(amount);// swap elements within the DOMfunction swapElements(obj1, obj2) {&nbsp; // create marker element and insert it above where obj1 is&nbsp; var temp = document.createElement("div");&nbsp; obj1.parentNode.insertBefore(temp, obj1);&nbsp; // move obj1 to right before obj2&nbsp; obj2.parentNode.insertBefore(obj1, obj2);&nbsp; // move obj2 to right before where obj1 used to be&nbsp; temp.parentNode.insertBefore(obj2, temp);&nbsp; // remove temporary marker node&nbsp; temp.parentNode.removeChild(temp);}// sort the divs within the DOMasync function sort(cancellationChecker) {&nbsp; for (let i = 1; i < amount; i++) {&nbsp; &nbsp; let j = i;&nbsp; &nbsp; for (j; j > 0; j--) {&nbsp; &nbsp; &nbsp; if (cancellationChecker()) return;&nbsp; &nbsp; &nbsp; if (+document.querySelectorAll('.sortBar')[j].getAttribute('value') < +document.querySelectorAll('.sortBar')[j-1].getAttribute('value')) {&nbsp; &nbsp; &nbsp; &nbsp; swapElements(document.querySelectorAll('.sortBar')[j], document.querySelectorAll('.sortBar')[j-1]);&nbsp; &nbsp; &nbsp; &nbsp; await delay(DELAY_BETWEEN_SWAPS);&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; }}function btnSort() {&nbsp; let cancelled = false;&nbsp; cancelLast();&nbsp; cancelLast = () => cancelled = true;&nbsp; sort(() => cancelled);}// Button to run the sort functionbutton = document.querySelector('.button');button.addEventListener('click', btnSort);* {&nbsp; box-sizing: border-box;&nbsp; margin: 0;&nbsp; padding: 0;}body {&nbsp; height: 100vh;&nbsp; width: 100%;}.sortDisplay {&nbsp; background-color: #305c50;&nbsp; background-image: linear-gradient(28deg, #305c50 0%, #6ab19e 70%, #82d8a6 100%);&nbsp; display: flex;&nbsp; align-items: flex-end;&nbsp; justify-content: space-between;&nbsp; height: 100%;&nbsp; width: 100%;&nbsp; overflow: hidden;}.btn-container {&nbsp; position: absolute;&nbsp; right: 0;&nbsp; bottom: 0;&nbsp; margin: 25px;}.btn-container button {&nbsp; padding: 25px;}.sortBar {&nbsp; flex: 1;&nbsp; background-color: #0007;}<div class="btn-container">&nbsp; <button class="reset">reset</button>&nbsp; <button class="button">button</button></div><div id="sortDisplay"class="sortDisplay"></div>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Html5