プロが教えるわが家の防犯対策術!

アコーディオン作成でぶつかってしまったので質問させてください。

下記サイトを参考にスマホサイトにアコーディオンを作成しました。
http://pops-web.com/main/html/demo-007.html


タブをクリックしたと同時に開かれているパネルの上部にスクロールさせたいのですが、
知識が貧しく苦戦しております。
理想は下記のURLのような動きにしたいと思っています。
http://lab.boy.jp/demo/accordion/index.html

どなたかお分かりの方がおられましたらご教授頂けないでしょうか。
宜しくお願いいたします。


<h3 class="trigger">ここにタイトル</h3>
<div class="content">
<div class="deta">ここに内容</div>
</div>

<h3 class="trigger">ここにタイトル</h3>
<div class="content">
<div class="deta">ここに内容</div>
</div>

</div>

//Accordion
(function($){

$(function(){

//オブジェクトを保存
var accordionItem=$('#accordion');
//一旦全部消す
accordionItem.find('.content').hide();

//active要素を指定して開く
var no=0;
accordionItem.find('.trigger').eq(no).addClass('active').next('.content').show();

//click-action
accordionItem.find('.trigger').click(function () {

//slide
$(this).next('.content').slideToggle('slow')
.siblings('div:visible').slideUp('slow');


//activeクラス切り替え
$(this).toggleClass('active');
$(this).siblings('.trigger').not($(this)).removeClass('active');


});

//hover-toggle
accordionItem.find('.trigger').hover(function () {

//toggle hoveredクラス
$(this).toggleClass('hovered');
return false;

});
});

})(jQuery);



「//activeクラス切り替え」の下に以下の2行を追加したのですが、
下の方のタブになるとスクロール位置が正しい位置にスクロールされませんでした。。
var scposi = $(".trigger.active").offset().top;
$('body,html').animate({ scrollTop: scposi });

A 回答 (3件)

ANo2です。

 こんにちは。

>他ページからのアクセスで、指定したパネルを開いた状態にすることは可能でしょうか?
原理的には可能と思います。
考え方や方法は検索すればたくさん見つかると思いますが、ご提示のHTMLソースの場合、各H3.targetあるいはDIV.contentの要素に個別の識別子が設定されていないので、通常よく用いられている方法は使えないですね。
ソースを修正するか別の方法で行うかということになりそうです。


別の方法の案の一例として…
「location.hashで指定する内容はアコーディオンの順番を示す」というようなルールを決めて、#menu0、#menu1・・・などという指定の仕方にしておくなら、そこから0、1・・・部分を取得して、それに対応するh3要素をクリックしてあげればよくなります。
この処理をonload時に行うようにしておけば良いでしょう。
(hashの指定がなければ0を指定されたことにする)


スクリプトをOFFにしている閲覧者に対して、できるだけ機能を損なわないようにすることを考えるなら、通常のページ内リンクが効くように、HTML内に識別子を設けておくほうがよろしいかと思います。
    • good
    • 0
この回答へのお礼

ありがとうございます!
ご回答頂き感謝いたします。

そうなんです。。
色々と調べてみたのですが、やりたい条件に全て合うものが中々見つからず困っております。。

(1)開閉連動型
(2)アイコン付き
(3)クリックに合わせて上部にスクロール

ここに、
(4)他ページからダイレクトにアクセス
を追加したいという感じです。
(1)~(3)までクリアできたので、あと1歩といったところです。。

下記のようにアコーディオンのコンテンツを囲む親要素を追加した方が宜しいでしょうか。。

<div class="block"> <!-- ←DIV要素を追加 -->
<h3 class="trigger">ここにタイトル</h3>
<div class="content">
<div class="deta">ここに内容</div>
</div>
</div>

<div class="block"> <!-- ←DIV要素を追加 -->
<h3 class="trigger">ここにタイトル</h3>
<div class="content">
<div class="deta">ここに内容</div>
</div>
</div>


location.hashについて、色々テストしながら試してみたいと思います。
現状の方法でやりやすい方法などヒントがでもいいんで、また教えて頂けたら幸いです。

お礼日時:2015/01/15 18:06

こんにちは。


スマホのコントロールは良くわからないのと、ざっと見ただけで試してはいませんので、違っているかも知れませんが…


>理想は下記のURLのような動きにしたいと思っています
そのスクリプトがどのようにしているかご覧になって見れば参考になるのでは?
そちらも、jQueryを使っているみたいですし、たいして長くはありませんので、読むのもそれほど大変ではないと思います。


ご提示のスクリプトで、
 var scposi = $(".trigger.active").offset().top;
を実行する際には、まだ開閉のアニメーションが始まったばかりの状態で、その状態でのtopの値を取得しますので、最終目標となるscrollTopの値が取得できるとは限らないように思えます。

対策としては、
1)アニメーションが終わってから、高さを取得し、スクロールする
2)一旦最終形の表示にして高さを取得し元に戻す。(=閲覧者には見えない)
  その後アニメーションとスクロールを同時に実行。
などの方法が考えられると思います。

ご提示のスクリプトでは一度に一か所しか開かないように制御していると思いますので、逐次topの値を取得しなくても、最初に全て閉じた状態でそれぞれのtopの値を取得しておくという方法の方が簡単かもしれませんね。
(他にも動的に高さが変わる要素がある場合は、事前取得ではうまくいきませんが。)
この方法でよければ・・・
//topの位置を初期保存
var topPos = [];
$('.trigger', accordionItem).each(function(i){
 topPos[i] = $(this).offset().top;
});

//スクロール
$('body,html').animate({ scrollTop: topPos[accordionItem.find('.trigger').index($(this))] });

みたいな感じでどうでしょうか。
( noって変数定義されてるけど更新してないのね…(^_^;) )

>下の方のタブになるとスクロール位置が正しい位置にスクロールされませんでした
対象の下方にコンテンツがない場合は、必ずしも一番上にh3が表示されるとは限りません。(理由はそれ以上スクロールできないから)

この回答への補足

もしお分かりであればでいいんですが、
こちらのコードで、他ページからのアクセスで、指定したパネルを開いた状態にすることは可能でしょうか?

$(location.hash).find(".acc_content").show();
他質問を参考に、上記を追加してみたのですがうまく動作せず、初歩的な事が分かっておらず大変恐縮ですが宜しくお願いいたします。

補足日時:2015/01/15 05:54
    • good
    • 0
この回答へのお礼

ありがとうございます!
お教え頂いたとおりにやってみました。
topPos[accordionItem.find('.trigger.active').index($(this))] });
上部の
.triggerのクラス名をtrigger.activeに修正し、思うように動作し
とても使いやすくなりました!

お礼日時:2015/01/15 05:54

slideToggle、slideUpの処理中にscrollTopが設定されてしまうからだと思います。



slideToggle、slideUpのコールバック関数(第二引数)でscrollTopを設定してみてはいかがでしょうか。
    • good
    • 0
この回答へのお礼

勉強不足で大変恐縮ですが、コールバック関数をどう設定したらいいか分かりません。。
参考にして調べたいと思います。ありがとうございます!

お礼日時:2015/01/15 05:56

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!