なぜ、実際には、ブロックでは発生しませんPromise.thenを使用してCSSプロパティを設定するのですか?

リチャード:

ボックスをクリックし、次のスニペットを試してみて、実行してください。

const box = document.querySelector('.box')
box.addEventListener('click', e => {
  if (!box.style.transform) {
    box.style.transform = 'translateX(100px)'
    new Promise(resolve => {
      setTimeout(() => {
        box.style.transition = 'none'
        box.style.transform = ''
        resolve('Transition complete')
      }, 2000)
    }).then(() => {
      box.style.transition = ''
    })
  }
})
.box {
  width: 100px;
  height: 100px;
  border-radius: 5px;
  background-color: #121212;
  transition: all 2s ease;
}
<div class = "box"></div>

何が起こることを期待します:

  • クリックして起こります
  • ボックスには、(このアクションは2秒かかります)100pxにすることにより、水平方向の変換を開始します
  • クリックで、新しいのPromiseも作成されます。内部は言ったPromisesetTimeout関数が2秒に設定されています
  • アクションは(2秒経過した)が完了した後、setTimeoutそのコールバック関数とセットを実行しますtransition誰にも負けません。それをやった後、setTimeoutまた戻りますtransformので、元の場所に現れるようにボックスを描画する、元の値に。
  • ボックスはありませんトランジション効果を元の場所に表示されますここでの問題
  • これらの仕上げのすべての後に、設定transitionを元の値にボックスバックの値を

見ることができるようにしかし、transition価値があるように見えるしませんnone実行している場合。私は、キーフレームを使用して例えば、上記を達成するための他の方法があることを知っているとtransitionend、なぜこれが起こるのでしょうか?私は明示的に設定transitionのみ元の値に戻った後、setTimeoutこのように約束を解決し、そのコールバックを終了します。

EDIT

要求ごととして、ここでの問題行動を表示するコードのGIFです: 問題

CertainPerformance:

イベントループバッチスタイル変更。あなたが1行に要素のスタイルを変更した場合、ブラウザはその変更をすぐに表示されません。それは次のアニメーションフレームまで待っています。これは、例えば、理由です

elm.style.width = '10px';
elm.style.width = '100px';

ちらつきが発生しません。ブラウザは、すべてのJavascriptが完了した後に設定されたスタイルの値を気に。

レンダリングが発生した後、すべてのJavascriptが、完了したマイクロタスクを含みます.then約束のマイクロタスクで発生する(効果的にすぐに他のすべてのJavascriptが終了したとしてとして実行されますが、何か他のものの前に-レンダリングなど-実行する機会がありました)。

あなたがやっていることは、あなたが設定しているあるtransitionにプロパティを''ブラウザのによる変化をレンダリングを開始する前に、マイクロタスクにstyle.transform = ''

あなたが後に空の文字列への移行リセットした場合requestAnimationFrame(すぐ隣の再描画の前に実行される)、その後、後にsetTimeout(ちょうど次の再描画後に実行される)、それがうまくいくと予想通り:

const box = document.querySelector('.box')
box.addEventListener('click', e => {
  if (!box.style.transform) {
    box.style.transform = 'translateX(100px)'
    setTimeout(() => {
      box.style.transition = 'none'
      box.style.transform = ''
      // resolve('Transition complete')
      requestAnimationFrame(() => {
        setTimeout(() => {
          box.style.transition = ''
        });
      });
    }, 2000)
  }
})
.box {
  width: 100px;
  height: 100px;
  border-radius: 5px;
  background-color: #121212;
  transition: all 2s ease;
}
<div class="box"></div>

おすすめ

転載: http://10.200.1.11:23101/article/api/json?id=7476&siteId=1