以前質問して解決したこちらの質問のサイトを
リニューアルすることになり、以前とほぼ同様の機能を実装しようとしたのですが、
以前とは微妙に違うエラーが発生してアコーディオン内のslickが実行されない問題が発生してしまいました。
結論から言うとアコーディオンを開いたタイミングでslickが初期化されていないため、
存在しないslickオブジェクトに対してslickSetOptionメソッドを実行しようとするためにエラーとなっている状況と思われます。
なのでアコーディオンを開いたタイミングでslickを初期化する処理を加えれば良いのではないかと思うのですが、
実行したいものが単純なslickスライダーではないため、どうするのが良いのか分かりません。
前提・実現したいこと
・カルーセル表示にはslick.jsを使用している(ver. 1.3.15)
・SPレイアウト(640px以下)ではアコーディオンパネルの中でカレンダーをカルーセル表示で見せる
・PCではアコーディオンなし/カルーセル表示なし
・ブラウザをリサイズしても上記表示を正常に切り替える
・カレンダー表示はアコーディオンの中で見せる場合と、そうでない場合の両方のパターンがある
・アコーディオンではない状態のカレンダー表示は、既存のinitCalendar()関数で正しく表示できている
発生している問題・エラーメッセージ
SPレイアウト時にアコーディオンを開くと、エラーが出てslick.jsの初期化が正しく行われない
該当のソースコード
HTML
1<div class="js-accordion"> 2 <h3 class="jy-routeCaption js-acrTitle">アコーディオン開閉見出し<span class="js-acrLabel">開く</span></h3> 3 <div class="js-acrBody"> 4 <div class="jy-calendar" data-month="12,1"> 5 <div class="cal"> 6 <table>省略 12月カレンダー</table> 7 </div><!-- /.cal --> 8 <div class="cal"> 9 <table>省略 1月カレンダー</table> 10 </div><!-- /.cal --> 11 </div><!-- /jy-calendar --> 12 </div><!-- /.js-acrBody --> 13</div><!-- /.js-accordion -->
JavaScript
1//ready 2$(function(){ 3 initCalendar(); //カレンダー初期化(※slick初期化含む) 4}); 5 6//load 7$(window).on('load', function(){ 8 accordionPanel01(); //アコーディオン開閉(※slick表示リフレッシュ含む) 9}); 10 11//resize 12var timer = false; 13$(window).resize(function() { 14 if (timer !== false) { 15 clearTimeout(timer); 16 } 17 timer = setTimeout(function() { 18 resetAccordionPane01(); //アコーディオン表示リセット 19 initCalendar(); //カレンダー初期化(※slick初期化含む) 20 }, 200); 21}); 22 23/* カレンダー初期化処理 24-------------------------------------------------- */ 25function initCalendar(){ 26 var $cal = $(".jy-calendar"); 27 var d = new Date(); //日時情報を取得 28 var month = String(d.getMonth()+1); //当月を取得して文字列に変換 29 var w = $(window).width(); 30 var size = 640; 31 32 $cal.each(function(){ 33 var len = $(this).find(".cal").length; 34 35 //アイテムが2つ以上だったら 36 if(len > 1){ 37 var calMonthText = $(this).data("month"); //掲載月データを取得 38 var calArray = String(calMonthText).split(","); //掲載月データを配列に変換 39 var num = $.inArray(month, calArray); //当月が何番目にあるかを取得 40 if(num < 0){ 41 num = 0; //当月が無かったら最初の月 42 } 43 //640px以下だったら(SPレイアウト時) 44 if (w <= size) { 45 if(!$(this).hasClass('slick-initialized')) { 46 $(this).slick({ //slickの初期化 47 initialSlide: num, 48 variableWidth: true, 49 centerMode: true 50 }); 51 $(this).find(".cal").matchHeight({ 52 remove: true 53 }); 54 } 55 //641px以上だったら(PCレイアウト時) 56 } else { 57 if($(this).hasClass('slick-initialized')) { 58 $(this).unslick(); //slickの解除 59 $(this).find(".cal").matchHeight(); 60 } 61 } 62 //アイテムが1つだったら 63 }else{ 64 $(this).find(".cal").addClass("center"); 65 return false; 66 } 67 }); 68} 69 70/* アコーディオン開閉処理 71-------------------------------------------------- */ 72function accordionPanel01() { 73 $(".js-acrTitle").on("click", function(){ 74 var w = $(window).width(); 75 var size = 640; 76 77 //640px以下だったら 78 if(w <= size){ 79 var $eventTarget = $(this); //.js-acrTitle 80 81 //アコーディオン開いている時の処理 82 if($(this).hasClass("op")){ 83 $(this).removeClass("op"); 84 $(this).find(".js-acrLabel").text("開く"); 85 $(this).next().stop().slideUp(400, function () { 86 // 87 }); 88 //アコーディオン閉じている時の処理 89 }else{ 90 $(this).addClass("op"); 91 $(this).find(".js-acrLabel").text("閉じる"); 92 $(this).next().stop().slideDown(400, function () { 93 //アコーディオンの中にカレンダーがあったら 94 if($eventTarget.next().has(".jy-calendar")){ 95 $eventTarget.next().find(".jy-calendar").slickSetOption(null, null, true);//slickの表示をリフレッシュ★エラーの原因箇所 96 } 97 } 98 }); 99 } 100 }else{ 101 return false; 102 } 103 }); 104} 105 106/* リサイズされた場合のアコーディオン表示処理 107-------------------------------------------------- */ 108function resetAccordionPane01() { 109 var w = $(window).width(); 110 var size = 640; 111 112 $(".js-accordion").each(function(){ 113 if (w <= size) { //SPの時 114 var display = $(this).find(".js-acrBody").css("display"); 115 if(display == "block"){//アコーディオンが開いていたら 116 $(this).find(".js-acrTitle").addClass("op"); //開閉アイコンの状態を設定 117 } 118 } else { //PCの時 119 //強制的にパネルを開く 120 $(this).find(".js-acrBody").show(); 121 $(this).find(".js-acrTitle").removeClass("op"); 122 } 123 }); 124}
試したこと
↓こちらはエラーこそ出ませんが、initCalendar()が実行されませんでした。
javaScript
1//アコーディオンの中にカレンダーがあったら 2if($eventTarget.next().has(".jy-calendar")){ 3 initCalendar(); //slickのリフレッシュの代わりにカレンダー表示の関数を入れてみる 4}
↓こちらはアコーディオンを開いた時にslickが実行されますが、
initCalendar()でやっている諸々の仕様(該当月を初期スライドにする、PCレイアウト時にはslickを解除するなど)の適用ができていないのでこれだけでは駄目です。
javaScript
1//アコーディオンの中にカレンダーがあったら 2if($eventTarget.next().has(".jy-calendar")){ 3 $(".jy-calendar").slick(); //ダイレクトにslickを実行してみる 4}
アドバイスいただきたいこと
・ すでに存在するinitCalendar()の関数を、アコーディオンを開くタイミングで実行する方法はありますか?
・ アコーディオンの中でカレンダーを表示する場合は既存のinitCalendar()とは別の処理(関数?)を用意しなければならないのでしょうか?
・何か他にエラーを起こすような問題が存在しているでしょうか?
解決の糸口が見つからない状態なので、何かアドバイスをいただけますと助かります。
よろしくお願い申し上げます。


回答1件
あなたの回答
tips
プレビュー