###実現したいこと
正しい順序でfadeOut系処理を実現したいです。
###発生している問題
以下jQueryについて、「お気に入りスレッド」を連続クリックすると、正しい順序で処理されず苦慮しております。
###操作画面
操作画面はこちらになり、右の「お気に入りスレッド」をクリックした際の処理が問題です。
###コンソール画面
上の「お気に入りスレッド」をクリックすると下図の上の4つが1セットでコンソール画面に表示されます。
しかし連続クリックしているうちにこの4つの順序が狂い、下図の下の2つのようになってしまうのです。
###該当のソースコード
長いコードとなっておりますので、まず実行可能なサンプルをjsfiddleでご用意いたしました。
https://jsfiddle.net/bq0v4wyz/
html
1<div class="wrapper"> 2 <div class="main"> 3 <div class="pagename">スレッド</div> 4 <h2 class="title" data-path="/threads/thread1/posts">カレーについて</h2> 5 <ul class="menu"> 6 <li data-menu="posts" class="is_active">コメント</li> 7 <li data-menu="followrs">フォロワー</li> 8 </ul> 9 <ul class="comments"> 10 <li>おいしい</li> 11 <li>すき</li> 12 </ul> 13 </div> 14 <div class="favorites"> 15 <p>お気に入りスレッド</p> 16 <ul> 17 <li data-path="/threads/thread2/posts">ケーキについて</li> 18 <li data-path="/threads/thread3/posts">ジャムについて</li> 19 <li data-path="/threads/thread4/posts">鍋について</li> 20 </ul> 21 </div> 22</div>
CSS
1.wrapper { 2 position: relative; 3 display: flex; 4 justify-content: space-evenly; 5} 6.wrapper > div { 7 position: relative; 8 width: 50%; 9 padding: 20px; 10} 11ul { 12 list-style: none; 13 margin: 0; 14 padding: 0; 15} 16p { 17 margin: 0; 18} 19.title { 20 margin: 0; 21} 22.menu { 23 display: flex; 24} 25.menu > li { 26 margin: 0 10px 0 0; 27} 28.menu > li.is_active { 29 border-bottom: 1px solid black; 30} 31.menu { 32 margin: 10px 0 10px 0; 33} 34.canopy { 35 font-weight: bold; 36 font-size: 1.5em; 37} 38.comments li, 39.favorites li { 40 background: pink; 41 padding: 5px; 42 margin: 5px 0 0px 0; 43 text-align: center; 44} 45.favorites { 46 background: #CCF; 47 padding: 10px; 48} 49.favorites li { 50 cursor: pointer; 51} 52.loader { 53 position: absolute; 54 top: 0; right: 0; bottom: 0; left :0; 55 display: flex; 56 align-items: center; 57 justify-content: center; 58 background: #eee; 59 z-index: 2; 60}
jQeury
1// リンクをクリックしてpjaxで遷移 2$(document).on('click','[data-path]', function(){ 3 console.log('%cクリックしました','color:red;'); 4 5 // 現在ページデータ 6 const currentPath = $('.title').data('path'), 7 currentTitle = $('.title').text(), 8 currentPagename = currentPath.split('/')[1]; 9 10 // 遷移先ページデータ 11 const targetPath = $(this).data('path'), 12 targetTitle = $(this).text(), 13 targetPagename = targetPath.split('/')[1]; 14 15 // ページデータ 16 const data = { 17 target : {path:targetPath, title:targetTitle, pagename:targetPagename}, 18 current: {path:currentPath,title:currentTitle,pagename:currentPagename}, 19 }; 20 21 // ページ遷移を実行 22 $('.main').prepend('<div class="loader">読込中</div>'); 23 fadeMain( data ); 24 pjaxMain( data ); 25}); 26 27// .main エリアのフェード 28function fadeMain( data ){ 29 const $fadeAreas = getFaeAreas( data ); 30 $fadeAreas.fadeOut(1000).promise().done( function () { 31 console.log('フェードアウト処理'); 32 33 // pagename 入れ替え 34 const pagenameJa = data.target.pagename === 'threads' ? 'スレッド' : 'ユーザー'; 35 $('.pagename').html( pagenameJa ); 36 37 // title 入れ替え 38 const title = data.target.title; 39 $('.title').html(title); 40 console.log('title =',title); 41 const path = data.target.path; 42 $('.title').data('path',path); 43 44 // 入れ替え終わったものを表示 45 $('.title, .pagename').fadeIn(200); 46 47 }); 48} 49 50// .mainエリアのpjax 51function pjaxMain( data ){ 52 const funcArr = getFuncArr( data ); 53 $.when.apply(null, funcArr).then( 54 function( resFuncArr ){ 55 //console.log('resFuncArr =', resFuncArr); 56 console.log('ここで履歴を保存'); 57 } 58 ); 59} 60 61// pjax時の関数を取得 62function getFuncArr( data ){ 63 let funcArr = []; 64 const func = $.when( ajaxComments() ).done( function( comments ){ 65 insertComments( comments, data ) 66 }); 67 funcArr.push( func ); 68 return funcArr; 69} 70 71// ajaxでコメントを取得してくる 72function ajaxComments(){ 73 const d = $.Deferred(); 74 setTimeout(function() { 75 const array = ["すき","おいしい","まずい","きらい","まぁまぁ","めっちゃすき"]; 76 const comments = array.slice().sort(function(){ return Math.random() - 0.5; }).slice(0, 2); 77 d.resolve( comments ); 78 }, 1000); 79 return d.promise(); 80} 81 82// コメントをHTMLに挿入 83function insertComments( comments, data ){ 84 let html = ''; 85 comments.forEach(function( comment ){ 86 html += `<li>${comment}</li>`; 87 }) 88 $('.comments').html( html ); 89 insertCommentsAfter( data ); 90} 91 92// コメント挿入後の処理 93function insertCommentsAfter( data ){ 94 const $fadeAreas = getFaeAreas( data ); 95 $fadeAreas.fadeIn(200).promise().done( function () { 96 $('.loader').remove(); 97 }); 98} 99 100// フェードエリアの取得 101function getFaeAreas( data ){ 102 let $fadeAreas; 103 if( data.current.path === data.target.path ){ 104 // 同じスレッドで.menuの変更の場合[ 105 $fadeAreas = $('.comments'); 106 }else{ 107 // 別スレッドの場合 108 $fadeAreas = $('.title, .pagename, .menu, .comments'); 109 } 110 return $fadeAreas; 111}
###試したこと1
アニメーションがうまく作動していないようなので、fadeOut()
やfadeIn()
の前に.stop()
を置いてみましたが変化ありませんでした。
jQeury
1$fadeAreas.fadeOut(1000).promise().done( function () { 2↓ 3$fadeAreas.stop().fadeOut(1000).promise().done( function () {
jQeury
1$fadeAreas.fadeIn(200).promise().done( function () { 2↓ 3$fadeAreas.stop().fadeIn(200).promise().done( function () {
###試したこと2
あとは次のように関数の前にまとめて.stop()
を置いてもみましたがこれもダメでした。
jQeury
1// リンクをクリックしてpjaxで遷移 2$(document).on('click','[data-path]', function(){ 3 4 /*--- 省略 ---*/ 5 6 // 関数の前にまとめてstop 7 const $fadeAreas = getFaeAreas( data ); 8 $fadeAreas.stop(); 9 10 // ページ遷移を実行 11 $('.main').prepend('<div class="loader">読込中</div>'); 12 fadeMain( data ); 13 pjaxMain( data ); 14});
###補足
jQeuryは3.4.1です。
現状の関数は削除せずに実現したいです。(質問のためにミニマムなコードにしていますが、実際にはいろいろな処理が絡んでいるためです。)
思い当たるポイントございましたらアドバイス宜しくお願い致します。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。