- ベストアンサー
質問:互換モード・標準準拠モードによるjqueryの動作
- アコーディオンメニューの設置を検討しているが、DOCTYPEによって不具合が発生。
- WindowsのIE6/7/8/9では不具合があり、Firefoxでは問題なし。
- DOCTYPEを保持しながら不具合を解消する方法と、不具合の理由を教えてほしい。
- みんなの回答 (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>
その他の回答 (2)
- fujillin
- ベストアンサー率61% (1594/2576)
#1です。 もう少しいじってみましたが、jqueryとは関係なさそうですね。 element.style.height = "0px"; を実行すると、IEは高さが0にならずに、指定なし(=本来の高さ)を確保してしまうようです。 (標準モードでは高さが0になります) それなので、折りたたむ時に高さ0を指定したときに、一瞬だけ全部の高さで表示されることが起きていると想像されます。 対応になってないけれど、とりあえずわかったことを…
お礼
fujillin様、度々お世話になります。 なるほど…。 ということは、たたむ際に「element.style.height = "0px";」を 実行させるスクリプトは、ライブラリがjqueryでなくともNG、 ということで相違ないでしょうか? うーん、キビしいですねぇ(笑)。。
- fujillin
- ベストアンサー率61% (1594/2576)
jqueryに明るくはないですが、簡単な実験をしてみました… 1)jquery uiをはずしてみる (jqueryのslide系のメソッドを利用) 2)jqyeryのanimateを利用 1)も2)もどうもダメみたいですね。 勝手な推測で言わせていただくと、animateの最後で一度もとのサイズに戻しているらしく、それが一瞬表示される原因ではないかと想像します。 (コードを確認したわけではありませんので、はずれている可能性も多々あります) 推測するところ、height:0にしたままにせずに、最後にheightを元に戻してdisplay:noneに設定し直しているのではないかと思いますが、その処理順序がdisplay:noneが後になっていて、一瞬表示されるのではないかと…(かなりの邪推かも) 一緒にopacityを0にすることで内容を見えなくすることは可能ですが、その下に表示されている要素が一瞬移動するので、あまり改善しているとは言えませんね。 いっそのこと… 求める機能がアコーディオンだけであるなら、jqueryを利用していないライブラリを試してみるか、または求める機能が決まっているのなら専用に自作してしまうか…でしょうか。
お礼
早速のご回答ありがとうございました。 お忙しい中実験を行っていただき感謝いたします。 Javascriptのコードは全く読めないのですが、 私も概ね同じような推測です。 やっぱり途中の処理に要因があるんでしょうね…。 jqueryを利用していないライブラリ…、というのも、 googleでの検索結果50件程度まで確認して 自分で扱えそうなものを10個程試したのですが、 DOCUTYPEを書き換えると動かなくなる、 そもそもIE6あたりでは動く気配もない、 といったものばかりでした。 今のところ、jqueryのものが一番惜しいという状況です。。 自作…、はできるほどのスキルがありません(涙)。 もうしばらく他の回答を待ってみようと思いますが、 頂いたものも大変参考になるご回答でした。 ありがとうございました。
お礼
おおお!スゴイっ! サンプルのものと若干動き方が違うところを見ると、 これはわざわざスクリプトを自作していただいたのでしょうか…!? めでたく自分の考えていた条件は揃いましたので、 これで行かせて頂きます! 貴重なお時間を沢山いただいてしまい大変恐縮です。。 本当にありがとうございました!