ホームページ  >  記事  >  ウェブフロントエンド  >  視覚的にバブルソート_html/css_WEB-ITnose

視覚的にバブルソート_html/css_WEB-ITnose

WBOY
WBOYオリジナル
2016-06-24 11:22:311095ブラウズ

これがアプリケーション全体の難しさだと思います。

visual.net を見ると、その実装は CSS3 のtransform関数のtranslateを使用しています。これは良いアイデアのように思えますが、translateに相当する値を取得するためにJSを使用するのは少し面倒であることがわかりました。

次に、別の回答の実装を調べました。彼の方法は、CSS で left を使用することです。 left の値は、position:relative が設定された親を基準とした相対値です。

上記の方法がよくわかりません。しかし、私は別の方法を考えました: left はそれ自体に対して相対的です 。つまり、それ自体を親ではなくposition:relativeに設定します。

.bar { position: relative; left: 0; /* must set, or not transition when value in falsy */ /*transition: left 1s;*/}

left を 0 に設定した理由は、CSS3 トランジションを使用してグラデーション効果を実現したいためです。

その後、交換するたびに、現在の左側に棒グラフの幅を加算/減算するだけで済みます。はい、これはこの方法の「欠点」の 1 つです。JS で縦棒グラフの幅を記述する必要があります。

swap () {  // ...  const getLeft = item =>    parseInt(item.style.left.slice(0, -2)) || 0 // rm 'px'  item1.style.left = `${this.barWidth + getLeft(item1)}px`  item2.style.left = `${-this.barWidth + getLeft(item2)}px`}

交換中、まず対応する DOM 要素 (上記のコードの item と item2) を見つける必要があります。

どうやって見つけますか? (大量の数値をソートしているとします) 最初に 2 つの方法を考えました。

最初の方法は、次のように、番号に基づいて一致する番号を持つ DOM 要素を見つけることです:

swap (value1, value2) {  const item1 = this.el.querySelector(`[data-value='${value1}']`)}

しかし、この方法は機能しません。なぜ?

同じ数値が複数ある場合、見つかった DOM 要素が交換したいものであるとは限りません。 querySelector は常に最初に一致する要素を返すためです。

item1 の後に item2 を探し始めてもいいですか? CSS3 ~ セレクターを使用します。例:

rrree

この方法は可能な場合もあれば、不可能な場合もあります。なぜ?

DOM 構造はまったく変わっていないため、CSS をそのまま使用して視覚的に位置を変更するだけです。

したがって、2 番目の方法は、当然 left の値を変更するだけでなく、交換中に DOM の位置も交換します。

swap (value1, value2) {  const item1 = this.el.querySelector(`[data-value='${value1}']`)  const item2 = this.el.querySelector(`[data-value='${value2}'] ~ data-value='${value2}']`)}

しかし、この方法はまだ機能しません。 insertBefore は DOM から element2 を削除するためです。この場合、「スワップ」グラデーション効果はありません。

案の定、まだ DOM 要素を使用できません。この場合、最初のメソッドのみを返すことができます。

この時、Reactでループする際にkey属性を書かなければいけないとふと思いました。それから。 。 。次に、キーと数値をバインドするだけで、その数値に対応する DOM 要素を見つけるには、キーを使用するだけで済みます。

function swapDOM(element1, element2) {  element1.parentNode.insertBefore(element2, element1);}

ついに「スワップ」アニメーションが完成しました。もっと良い実装方法はありますか?

「スワップ」アニメーションが一瞬で切れてしまったのはなぜですか?

並べ替えアルゴリズムが次のようになっているとします。

// data = [64, 39, 78, 36]this.items = data.map((d, i) => ({key: `key-${i}`, value: d}))swap (key1, key2) {  const item1 = this.el.querySelector(`[data-key='${key1}']`)}

これは正しくありません。 。

ただし、「スワップ」アニメーションは実行を終了しており、グラデーション効果はまったくありません。次のスワップ アニメーションが実行される前に、前のスワップ アニメーションが完了するまで待機する必要があります。なぜこうなった?なぜなら、私たちの 2 つの for は瞬時に実行できるからです = =

この問題を解決するにはどうすればよいでしょうか?間隔を設定しますか?並べ替えアルゴリズムのロジックが混乱するようです。

突然、jQuery にはアニメーションキューがあるらしいと思いました。

つまり、最初にすべてのアニメーションをキューに入れることができます。次に、1 つずつデキューし、1 つずつ呼び出します。

sort () {  const items = this.items  for (let i = 0; i < items.length; i++) {    for (let j = 0; j < items.length - i - 1; j++) {      const item1 = items[j]      const item2 = items[j + 1]      if (less(item2.value, item1.value)) {        swap(j, j + 1, items)      }    }  }  return this.items}

Zhihu の回答を読んだ後、この問題を実装する他の方法があります。 一般的に、非同期プログラミングの問題を解決する方法。

ヒント

CSS 疑似要素 ::before と attr 関数を使用して、対応する数値を棒グラフに表示できます。

for () {  for () {    if (less(item2.value, item1.value)) {      this.queue.push(() => this.swap(item1.key, item2.key))    }  }}play () {  const intervalId = setInterval(() => {    if (this.queue.length === 0) {      clearInterval(intervalId)    } else {      const swap = this.queue.shift()      swap()    }  }, 2 * 1000)}

Continue

私たちのコードは、他の並べ替えアルゴリズムに拡張できるようにインターフェイスを設計する方法など、最適化を続けることができます。また、並べ替え前、並べ替え中、並べ替え後の状態の色を異なる色に設定するなど、ユーザー エクスペリエンスも考慮されています。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。