実現したいこと
JavaScriptのtransitionend
をキャンセルできないでしょうか?
発生している問題
if
の中を通っていないのに、if
の中のtransitionend
の処理が走ってしまいます。
該当のソースコード
次のソースコードはchangeBox()
をこのように2回処理をしています。
1回目
➀ changeBox()
の type
に null
を渡す
➁ .box
に transitionend
をかけ、p.text( 'いいい' );
にする
2回目
➂ changeBox()
の type
に 'show'
を渡す
④ p.text( 'あああ' );
にする
なのに2回目に'いいい'
になってしまうのです。
https://jsfiddle.net/omLy95bq/
html
1<p>●●●</p> 2<div class="box">box</div>
css
1.box { 2 transition: 1s; 3 background: gray; 4} 5.box.is_red { 6 background: pink; 7} 8.box.is_blue { 9 background: skyblue; 10}
JavaScript
1$(function(){ 2 3 changeBox( null ); // 1回目 4 changeBox( 'show' ); // 2回目 5 6 function changeBox( type ) { 7 8 if ( type == 'show' || type === 'up' || type === 'down' ) { 9 $( 'p' ).text( 'あああ' ); 10 } 11 12 $( '.box' ).addClass( type === null ? 'is_red' : 'is_blue' ); 13 14 if ( type === null ) { 15 $( '.box' ).on('transitionend', function() { 16 $( 'p' ).text( 'いいい' ); 17 }); 18 } 19 20 } 21 22});
試したこと
試したこと➀:時間差の確認
'いいい'
にしたいのはnull
を渡した場合だけなのに、なぜこうなってしまうのか?
まず考えたのはtransition: 1s;
の途中で2回目を実行しているせいか?という疑念で、その確認のために2回目をsetTimeout
で実行しました。しかし変化なく、相変わらず2回目に'いいい'
になってしまいます。
https://jsfiddle.net/omLy95bq/1/
JavaScript
1$(function(){ 2 3 changeBox( null ); // 1回目 4 // changeBox( 'show' ); // 2回目 5 setTimeout( ()=>{ changeBox( 'show' ); }, 5000 ); // 2回目 6 7 /* 8 省略 9 */ 10 11});
試したこと②:コンソールの確認
次に各所でコンソールを確認してみました。
1回目は'nullが渡されました'
と'いいいにします'
が出力されるのですが、
2回目は'あああにします'
と'いいいにします'
が出力されます。
つまり2回目はif
の中('nullが渡されました'
)を通っているわけではなく、しかしif
の中のtransitionend
の中('いいいにします'
)を通っているように見受けられました。
https://jsfiddle.net/omLy95bq/2/
JavaScript
1$(function(){ 2 3 changeBox( null ); // 1回目 4 // changeBox( 'show' ); // 2回目 5 setTimeout( ()=>{ changeBox( 'show' ); }, 5000 ); // 2回目 6 7 function changeBox( type ) { 8 9 if ( type == 'show' || type === 'up' || type === 'down' ) { 10 console.log('あああにします'); 11 $( 'p' ).text( 'あああ' ); 12 } 13 14 $( '.box' ).addClass( type === null ? 'is_red' : 'is_blue' ); 15 16 if ( type === null ) { 17 console.log('nullが渡されました'); 18 $( '.box' ).on('transitionend', function() { 19 console.log('いいいにします'); 20 $( 'p' ).text( 'いいい' ); 21 }); 22 } 23 24 } 25 26});
以上のことから、1回目でtransitionend
の処理がどこかに登録(?)されたまま、2回目の実行ではその登録は解除されず、処理が走ってしまうという状況のように思われます。
そこでタイトルの質問になります。
「transitionend」をキャンセルできないでしょうか?
具体的にイメージしているのは次のようなキャンセルで、これなら2回目に 'show' を渡した時点で、1回目に登録された処理は走らないだろうという目論見です。
JavaScript
1 if ( type == 'show' || type === 'up' || type === 'down' ) { 2 $( '.box' ).on('cancelTransitionend'); // 「transitionend」をキャンセル 3 $( 'p' ).text( 'あああ' ); 4 }
バージョン
jQuery 3.6.0
補足
尚、MDNを見るとtransitioncancel
というそれっぽい名前の関数があったのですが、これは登録されているtransitionend
をキャンセルするのではなく、CSSのtransition
が途中でキャンセルされたときに発火させたいイベントを登録する関数のようです。
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/09/25 20:06
2022/09/26 11:48