25

CSS遷移をバイパスして、プロパティをすぐに変更したい。変更前に設定
transition-durationてから、元の値に戻そうとしました。0stransition-duration

$('div').css('width', '200px').delay(1000).queue(function() {
    $(this).css({
        transitionDuration: '0s',
        msTransitionDuration: '0s',
        mozTransitionDuration: '0s',
        webkitTransitionDuration: '0s',
        oTransitionDuration:'0s'
    }).css('width', '10px').css({
        transitionDuration: '2s',
        msTransitionDuration: '2s',
        mozTransitionDuration: '2s',
        webkitTransitionDuration: '2s',
        oTransitionDuration:'2s'
    })
})​

フィドル
これは明らかに機能しません。

私は、仕様がこのためのその動作を定義していないことを理解しています:

この仕様では、計算値がいつ変更されるかを定義していないため、計算値への変更が同時に行われると見なされるため、遷移する可能性のある変更を行った後、遷移プロパティを少し変更すると、次のような動作が発生する可能性があることに注意してください。一部の実装では変更が同時に行われると見なされる場合がありますが、他の実装では考慮されない場合があるため、実装によって異なります。

これを行う簡単な方法はありますか?

注:私が変更しているプロパティはtransformそうなので.animate()、オプションではありません。

4

10 に答える 10

13

他の誰も有効な答えを投稿していないので、ここに行きます:

$('div').css('width', '200px').delay(1000).queue(function() {
    $(this).css({transition: '0s', width: '10px'}).delay(1).queue(function() {
        $(this).css({transition:'2s'});
    });
},1000)​;

フィドル

または、それが逆の場合:

$('div').css({
    transition: '0s'
  }).css('width', '200px').delay(1000).queue(function() {
      $(this).css({width: '10px', transition: '2s'});
});

フィドル

最近、jQueryはベンダープレフィックスを正規化する必要があるため、すべてを自分で入力する必要はありません。


ここでの問題は、jQueryがすべてのスタイルを一度にアタッチし、最後のスタイルのみを保持し、DOMの再描画を行わずに同じCSSプロパティの以前のスタイルを上書きし、ネイティブjavascriptでのテストが同じことを行うように見えることです。したがって、おそらくブラウザは、次のコード行でスタイルを変更するためだけにスタイルを追加することで、不必要なリフローを回避しようとしているので、次のようになります。

$('div').css({
    transition: '0s',
    width: 200
}).css({
    transition: '3s',
    width: 10
});

最後のスタイルのみが追加されるため、機能しません。

ここで問題が発生delay()します。OPの質問はすでに使用されていdelay()たため、使用しない理由はありませんでしたが、削除delay()すると、ブラウザが最初のスタイルをペイントせず、最後のスタイルのみをペイントするという上記の問題が発生します。

実際delay()には単なる空想的なタイムアウトであるため、スタイルの2番目の設定の実行を効果的に延期し、2回のブラウザーの再描画を引き起こします。

これはブラウザの問題である可能性が高く、変更できるものではないため、2番目のスタイルの設定を延期することがこれを機能させる唯一の方法であり、遅延を使用すると、1ミリ秒または1ミリ秒に設定されている場合でも機能します。スクリプトの実行を延期する通常の方法である、通常のタイムアウトで実行を延期することができます。

$('div').css({
    transition: '0s',
    width: 200
});

setTimeout(function() {
    $('div').css({
        transition: '3s',
        width: 10
    });
});

フィドル

タイムアウトによりスタイルの最初の設定がブラウザによって描画され、タイムアウト内のスタイルの設定が後で延期されるため、上記は問題なく機能しますが、時間が設定されていないため、すぐに実行されますブラウザができるように(ただし、現在のスクリプトが完了するまで延期されます)、人間の目にはすぐに見えるようになり、問題が解決します。

于 2012-12-02T15:33:27.970 に答える
4

CSSを管理している場合

最も簡単な方法は、アニメーションをあるクラスに結び付けてから、アニメーションをバイパスしないようにする時点でクラスを追加します。そうしないと、アニメーションが設定されません。逆の場合、通常はアニメーションが必要ですが、場合によってはそれをバイパスしたい場合は、デフォルトでクラスを追加し、バイパス時に削除します。

CSSの例

div{
    height: 100px;
    width: 200px;
    background: red;
}
div.doTransition {
    width: 10px;
    transition: width 2s linear;
    -ms-transition: width 2s linear;
    -moz-transition: width 2s linear;
    -webkit-transition: width 2s linear;
    -o-transition: width 2s linear;
}

必要なときにアニメーションを開始するためのクリックイベントを作成するフィドルを参照してください。ただし、これは、クラスをバイパスしたくないときにクラスを追加する他のプログラムトリガーである可能性があります。このフィドルは逆のことを行い、アニメーションが存在することを前提としていますが、ページの読み込み時にクラスを削除することですぐにバイパスします。

于 2013-11-26T17:09:29.510 に答える
4

適用された要素のcss遷移を無効にするオーバーライドクラスを設定すると、!importantこれに最適です。

.notransition {
  -webkit-transition: none !important;
  -moz-transition: none !important;
  -o-transition: none !important;
  -ms-transition: none !important;
  transition: none !important;
}

toggleClassこれで、目的の動作(スムーズな遷移と瞬時の変更)を切り替えることができます。

$('div').
toggleClass('notransition', true). //or false!
css('width', '200px');

いじる。このアプローチのIMOの利点の1つは、デフォルトの要素スタイルとすべてのスムーズアニメーションの無効化フラグを明確に分離できることです。これは、非常に「ラップ可能な」再利用可能なアプローチでもあります。つまり、トランジションを使用して実行する必要があるかどうかを示すオプションのブールプロパティを既存のメソッドに簡単に追加できます。

注意:パフォーマンスやUXの理由で、ページのトランジションを完全に無効にしたい場合があります。その場合、セレクターをに変更して.notransition *、すべての子孫要素の遷移を無効にすることができます。

于 2013-11-27T23:55:46.040 に答える
3

問題は、ブラウザが速度を落とし、各操作を別々に実行する理由がないため、ブラウザがそれらを組み合わせて同時に両方を実行することです。クエリoffsetHeight は、高さを再計算する必要があるため、各操作を個別に実行するように強制する1つの方法です。http://jsfiddle.net/markasoftware/6cTeY/15/は完全に機能します

于 2013-11-28T00:09:09.863 に答える
1

これが私がそれを機能させる唯一の方法です。jQueryは少し頑固なようです。

http://fiddle.jshell.net/8qTpe/1/

PSあなたのアプローチにはいくつかのエラーがあります:

  1. 遅延前に200pxにサイズ変更しているため、デフォルトのCSS設定を使用しています。

  2. トランジションを2秒に戻す前に、サイズを10pxに変更しています。

現在、jQueryはすべてのCSS設定を連続して適用しているように見えるため、すべてが機能していないように見えます。

于 2013-11-28T20:39:39.987 に答える
1

私はかなりクリーンなCSSソリューションを選びます

HTML

<div id="foo"></div>
<button class="out">out</button>
<button class="in">in</button>

JS

$('button.out').click(function(){console.log($('#foo').addClass);$('#foo').addClass('out')})
$('button.in').click(function(){$('#foo').removeClass('out')})

CSS

div{
    height: 100px;
    width: 10px;
    background: red;

    transition: width 0s linear;
    -ms-transition: width 0s linear;
    -moz-transition: width 0s linear;
    -webkit-transition: width 0s linear;
    -o-transition: width 0s linear;
}
div.out {
    width: 200px;
    transition: width 2s linear;
    -ms-transition: width 2s linear;
    -moz-transition: width 2s linear;
    -webkit-transition: width 2s linear;
    -o-transition: width 2s linear;

}

http://jsfiddle.net/6cTeY/19/

于 2013-11-30T14:04:54.573 に答える
1

私は通常、このバニラJSの方法でそれを行います。

フィドル

HTML

あなたが要素を持っているとしましょう

<div id="element"></div>

CSS

要素にCSSトランジションがすでにアクティブで、背景が緑であるとします。

#element {
    background: green;
    width: 200px;
    height: 200px;
    -webkit-transition: 'all 0.5s ease-out';
    -moz-transition: 'all 0.5s ease-out';
    -ms-transition: 'all 0.5s ease-out';
    -o-transition: 'all 0.5s ease-out';
}

JS

要素にはCSSトランジションがありますが、要素の背景を即座にBLUEに変更したいと思います。

その直後に、要素の通常の動作を戻し、背景をREDにアニメートできるようにします。

トランジションを一時的に停止し、すぐに復元する必要があります。

// grab the element
var element = document.getElementById('element');

// removeTransitions
element.style.webkitTransition   = 'none';
element.style.mozTransition      = 'none';
element.style.msTransition       = 'none';
element.style.oTransition        = 'none';

// apply desired 'instant' property
element.style.background         = 'blue'; // is applied instantly

// this 10ms timeout is necessary for the transitions to be active again
setTimeout(function() {
    element.style.webkitTransition   = 'all 5s ease-out';
    element.style.mozTransition      = 'all 5s ease-out';
    element.style.msTransition       = 'all 5s ease-out';
    element.style.oTransition        = 'all 5s ease-out';

    // apply desired 'animated' property
    element.style.background         = 'red';  // is applied smoothly
}, 10);
于 2015-07-19T05:09:40.390 に答える
0

var ball = document.querySelector('.ball'),
    ballSpeed = 2,
    button = document.querySelector('button');

// Chane to random speed "instantly" (on button "click")
button.addEventListener('click', ()=>{ 
  ballSpeed = Math.random()*8 + 1;
  
  ball.style.transitionDuration = ballSpeed + 's';
  ball.classList.remove('move');
  ball.clientHeight; // <--- triggers repaint
  ball.classList.add('move');
  
  // set button text
  button.textContent = ballSpeed.toFixed(2) + 's';
})

function animate( speed ){
  ball.style.transitionDuration = '0s';
  ball.classList.remove('move');
  ball.clientHeight; // <--- triggers repaint. has to be after "move" class was removed
  
  ball.style.transitionDuration = ballSpeed + 's';
  ball.classList.add('move');
  ball.removeEventListener('transitionend', animate)
  ball.addEventListener('transitionend', animate); // keep rollin..
}

animate();
html, body{ height:100%; overflow:hidden; } 

.ball{
  position: absolute;
  width: 3em;
  height: 3em;
  left:0; right:0; top:0; bottom:0;
  margin: auto;
  
  transition-duration: 2s; /* <-- start speed  */
  transition-timing-function: linear;
}

.ball::after{
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  transform: translateX(100%);
  border-radius:50%;
  background: gold;
}

.ball.move{
  transform: rotate(360deg);
}
<button>2s</button>
<div class="ball"></div>

于 2018-07-11T09:14:55.047 に答える
0

これがJQueryでどのように機能するかはわかりませんが、CSSでこれを行うことができます(少なくとも執筆時点では)。

div {
  animation: trans 2s;
}

@keyframes trans {
  0% {
    width: 200px;
  }
  99.9% {
    width: 200px;
  }
  100% {
    width: 10px;
  }
}
于 2021-01-08T03:37:51.120 に答える
0

JQueryで動作するはずの純粋なJSソリューション(テストされていません)。

受け入れられた回答の問題は、遅延の値を設定することですが、より良い解決策は、遅延を0にすることです。これを実現するために、イベントループで少しトリックを使用します。

const button = document.querySelector('button');

function reposition() {
  button.style.transition = 'none';
  button.style.transform = 'translate(-50%)';
  
  setTimeout(() => {
    button.style.transition = '1s';
    button.style.transform = 'translate(0)';
  }, 0);
}

button.addEventListener('click', reposition);
<button>
    Click Me
</button>

これはゼロ遅延と呼ばれます。それでも遅延を使用しますが、スタックがクリアされるとすぐに実行されるため、これについて不快に感じる必要はありません。

これがなぜであるかを理解したい場合は、このビデオを見ることをお勧めします

しかし、ここに(厄介な)簡単な説明があります:

基本的に何が起こっているのかというと、setTimeout()は特定の時間まで値を保持します。ここでの時間は0ですが、スタックがクリアされるまでまだ実行されません(なぜですか?これはビデオを見てください)。ブラウザはまだ変更を再描画する必要があり、再レンダリングはスタックに残り、終了すると、setTimeout()に渡された関数が実行され、別の再レンダリングが発生します。

これが100%機能するかどうかわかりますか?理論的にはそうすべきですが、私は専門家ではありません。

于 2021-06-12T02:57:57.743 に答える