重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

■現状
 アコーディオンメニューの設置を検討しているのですが、
 使用したいDOCTYPEでは若干の不具合が発生しまいました。

■環境
 Windows IE6/7/8/9のすべてで発生、FirefoxはOKでした


■頂きたい回答
 まず、DOCTYPEを保持したままでこの不具合が解消できるのか否か、
 もしできるのであればその方法をお願いしたいと思います。
 また、可能であれば「○○の部分でjqueryの計算が△△している」など、
 不具合の理由もざっくりで良いので、教えて頂ければ大変ありがたいです。




■サンプルソール(MediaFire、広告が出ますがご了承下さい。。)
 http://www.mediafire.com/?yx1pqxbt9tipifk


■不具合詳細
 下記サイトを参考にアコーディオンメニューを設置しました。
 http://www.geekzshu.com/jquery/975
 ところが、DOCTYPE宣言により「互換モード」になっている場合、
 メニューを開く⇒閉じると、一瞬メニューの中身が表示されてしまいます。

 なお、他サイトのサンプルを改造しても、jquery+互換モードの組み合わせになると
 閉じる際に同じような現象が発生するようでした。



jqueryに明るい方、大変お手数をおかけいたしますが、
何卒宜しくお願いいたします。

A 回答 (3件)

こんにちは。



とりあえず、要領のみということで書いてみました。
書き放しなので、効率もよくないしかなりいい加減です。
(全角空白は半角に)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="ja">
<head><title>test</title>
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Content-Script-Type" content="text/javascript">

<style type="text/css">
<!--
.accordion { width:600px; }
.accordion h5 { cursor:pointer; }
.accordion h5.active { background-color:#eef; }
.accordion p { overflow:hidden; }
//-->
</style>
</head>
<body>

<div class="accordion">
<div>
<h5>アコーディオン1</h5>
<p>こんにちは、ぼくはアコーディオン1号です。こんにちは、ぼくはアコーディオン1号です。こんにちは、ぼくはアコーディオン1号です。 </p>
</div>
<div>
<h5>アコーディオン2</h5>
<p>こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。</p>
</div>
<div>
<h5>アコーディオン3</h5>
<p>こんにちは、ぼくはアコーディオン3号です。こんにちは、ぼくはアコーディオン3号です。こんにちは、ぼくはアコーディオン3号です。こんにちは、ぼくはアコーディオン3号です。こんにちは、ぼくはアコーディオン3号です。こんにちは、ぼくはアコーディオン3号です。</p>
</div>
</div>

<hr>
<div class="accordion">
<div>
<h5>アコーディオン1</h5>
<p>こんにちは、ぼくはアコーディオン1号です。こんにちは、ぼくはアコーディオン1号です。こんにちは、ぼくはアコーディオン1号です。 </p>
</div>
<div>
<h5>アコーディオン2</h5>
<p>こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。こんにちは、ぼくはアコーディオン2号です。</p>
</div>
<div>
<h5>アコーディオン3</h5>
<p>こんにちは、ぼくはアコーディオン3号です。こんにちは、ぼくはアコーディオン3号です。こんにちは、ぼくはアコーディオン3号です。こんにちは、ぼくはアコーディオン3号です。こんにちは、ぼくはアコーディオン3号です。こんにちは、ぼくはアコーディオン3号です。</p>
</div>
</div>



<script type="text/javascript">
<!--
var Accordion = function(ac){
 var animate = [];

 var getHeight = function(elm){
  var s = elm.style;
  var h = s.height, d = s.display;
  s.height = "", s.display = "block";
  var height = elm.clientHeight || elm.offsetHeight;
  s.display = d, s.height = h;
  d = d!="none";
  h = h!==""?parseInt(h):d?height:0;
  return { height:height, h:h, display:d };
 }

 var getNodes = function(elm){
  var result = [];
  var i, d, t, p, div = elm.childNodes;
  for(i=0; d=div[i++];){
   if(d.nodeName=="DIV"){
    t = d.getElementsByTagName("h5");
    if(t.length){
     p = t = t[0];
     while(p && p.nodeName!="P") p = p.nextSibling;
     result.push({ title:t, element:p });
    }
   }
  }
  return result;
 }

 var slide = function(elm, dir){
  var hh = getHeight(elm), style = elm.style;
  var h = hh.h, end = dir>0?hh.height:0;
  if(0>dir && !hh.display) return;
  if(dir>0 && 0==h){ style.height = "1px"; style.display = "block"; }
  var id = setInterval(function(){
   h += dir;
   if((dir>0 && h>end) || (0>dir && end>h)) h = end;
   if(0==h) style.display = "none";
   style.height = h + "px";
   if(h==end) clearInterval(id);
  }, 15);
  animate.push(id);
 }

 var setAnimation = function(elm, f){
  if(!elm.element) return;
  var cls = elm.title.className, disp = /(^| )active( |$)/.test(cls);
  var dir = (f && !disp)?4:-4;
  cls = cls.replace(/ active/, "");
  if(dir>0) cls += " active";
  elm.title.className = cls;
  slide(elm.element, dir);
 }

 var func = function(evt){
  var t = evt.target || evt.srcElement, p = t.parentNode;
  if(t.nodeName != "H5" || !p || !(p=p.parentNode)) return;
  if(!/(^| )accordion( |$)/.test(p.className)) return;
  var i, e, dir, elements = getNodes(p);
  while(e = animate.shift()) clearInterval(e);
  for(i=0; e=elements[i++];) setAnimation(e, e.title==t);
 }

 var i, pair = getNodes(ac);
 for(i=0; pair[i]; i++){
  pair[i].element.style.display = "none";
 }
 try{ ac.addEventListener("click", function(e){func(e)}, false); }
  catch(e){ ac.attachEvent("onclick", function(e){func(e)}); }
 ac = null;
}

window.onload = function(){
 var i, d;
 var div = document.getElementsByTagName("div");
 for(i=0; d=div[i++];)
  if(/(^| )accordion( |$)/.test(d.className)) Accordion(d);
}
//-->
</script>
</body>
</html>
    • good
    • 0
この回答へのお礼

おおお!スゴイっ!
サンプルのものと若干動き方が違うところを見ると、
これはわざわざスクリプトを自作していただいたのでしょうか…!?
めでたく自分の考えていた条件は揃いましたので、
これで行かせて頂きます!

貴重なお時間を沢山いただいてしまい大変恐縮です。。
本当にありがとうございました!

お礼日時:2012/03/17 03:15

#1です。



もう少しいじってみましたが、jqueryとは関係なさそうですね。

 element.style.height = "0px";
を実行すると、IEは高さが0にならずに、指定なし(=本来の高さ)を確保してしまうようです。
(標準モードでは高さが0になります)

それなので、折りたたむ時に高さ0を指定したときに、一瞬だけ全部の高さで表示されることが起きていると想像されます。

対応になってないけれど、とりあえずわかったことを…
    • good
    • 0
この回答へのお礼

fujillin様、度々お世話になります。

なるほど…。
ということは、たたむ際に「element.style.height = "0px";」を
実行させるスクリプトは、ライブラリがjqueryでなくともNG、
ということで相違ないでしょうか?

うーん、キビしいですねぇ(笑)。。

お礼日時:2012/03/15 14:52

jqueryに明るくはないですが、簡単な実験をしてみました…



1)jquery uiをはずしてみる
 (jqueryのslide系のメソッドを利用)
2)jqyeryのanimateを利用

1)も2)もどうもダメみたいですね。
勝手な推測で言わせていただくと、animateの最後で一度もとのサイズに戻しているらしく、それが一瞬表示される原因ではないかと想像します。
(コードを確認したわけではありませんので、はずれている可能性も多々あります)

推測するところ、height:0にしたままにせずに、最後にheightを元に戻してdisplay:noneに設定し直しているのではないかと思いますが、その処理順序がdisplay:noneが後になっていて、一瞬表示されるのではないかと…(かなりの邪推かも)

一緒にopacityを0にすることで内容を見えなくすることは可能ですが、その下に表示されている要素が一瞬移動するので、あまり改善しているとは言えませんね。


いっそのこと…
求める機能がアコーディオンだけであるなら、jqueryを利用していないライブラリを試してみるか、または求める機能が決まっているのなら専用に自作してしまうか…でしょうか。
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございました。
お忙しい中実験を行っていただき感謝いたします。

Javascriptのコードは全く読めないのですが、
私も概ね同じような推測です。
やっぱり途中の処理に要因があるんでしょうね…。

jqueryを利用していないライブラリ…、というのも、
googleでの検索結果50件程度まで確認して
自分で扱えそうなものを10個程試したのですが、
DOCUTYPEを書き換えると動かなくなる、
そもそもIE6あたりでは動く気配もない、
といったものばかりでした。
今のところ、jqueryのものが一番惜しいという状況です。。

自作…、はできるほどのスキルがありません(涙)。

もうしばらく他の回答を待ってみようと思いますが、
頂いたものも大変参考になるご回答でした。
ありがとうございました。

お礼日時:2012/03/14 23:52

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