ブラウザ依存の悩み
Javascript、DOM、CSSに関する質問に回答しました。
報酬1000pt。JAVASCRIPTのお話です。class=”nullpo”の要素のstyle.displayの値をnoneにする簡潔なスクリプトを教えてください。★ノリ的には複雑なスクリプトよりもbookmarklet的な簡素なものを希望しています。IE5、Firefoxの両方で動いてくれればバッチリです。こんな使い方して申し訳ありませんが、よろしくお願い致します。
検討のポイント
1)スタイルシートのdisplay属性をnoneに変更
属性を変更する対象が特定できれば、「オブジェクト.style.display="none"」で設定できます。
2)特定のclassが指定された複数の要素を対象にする
特定の要素を1つだけ対象にする場合は、
document.getElementByID()
を使用します。ただし、要素にドキュメント内でユニークなIDを設定しておく必要があります。
name属性が同一のものを複数対象にする場合は
document.getElementsByName()
同一のタグを複数対象にする場合は
document.getElementsByTagName()
を使用します。
しかし、今回は、同一のclassが指定された複数の要素が対象です。document.getElementsByClass()というのは無い様なので、ドキュメントに存在する全ての要素を順に処理して、classの値が条件に合うものだけを対象に処理する必要があります。
問題は、IEであれば、document.allで全ての要素を取得できるのですが、W3C標準では推奨しておらず、NetscapeやSafariでは使用できません。(FirefoxとOperaはOK)
今回は、用途を限定し、document.getElementsByTagName('div')として、特定のタグ名(div)のみを対象にする事にしました。質問者の方も、それで十分だと言う事です。
3)ブックマークレットに使える程度に簡易なスクリプトにする
実際にブックマークレットに出来る様、<a href="javascript:〜">で試して、回答しました。href=の中は、
javascript:(function(){〜})();
として、{〜}に処理を記述します。
コーディング
ブックマークレット用ではなく、改行を入れて読み易くすると、以下の通り。
タグはdivのみ、さらにclass='myClass'のものだけを対象として、displayをnoneにします。
for(ii=0; ii<document.getElementsByTagName('div').length; ii++){ myObj=document.getElementsByTagName('div')[ii]; if(myObj.className=='myClass'){ myObj.style.display='none'; } }
また、IE等、document.allが使用できるブラウザだけを対象にするのであれば、次の通り。
for(ii=0;ii<document.all.length;ii++){ myObj=document.all[ii]; if(myObj.className=='myClass'){ myObj.style.display='none'; } }
検討継続
「ブックマークレットに使える程度に簡易なスクリプト」という点を考慮し、ブラウザによる処理の振り分けはしませんでしたが、W3C標準でdocument.allと同じ事が出来ないかどうか気になったので、自分でも質問することにしました。
JavascriptとDOMの質問です。IEで使えるdocument.allの様に、W3C標準でdocument内の全ての要素を集合で取得する方法は無いでしょうか。document.getElementsByNameやdocument.getElementsByTagNameでは、条件に一致するものしか取得できない様で、無条件にする方法が解りません。なお、OperaやFireFoxでは、document.allが使えてしまう様ですが、NetscapeやSafariでも使用可能な方法で、回答お願いします。
質問開始から約9時間の時点で、1件しか回答が無いのですが、有効な回答を頂きました。
document.getElementsByTagName()で、ワイルドカードとして*が使える様です。
早速試してみましたが、ブラウザとバージョンによって、使用できない場合がありました。document.allと合わせて整理すると下表の通りです。
IE6.0 | IE5.5 | Netscape7.1 | Firefox1.0 | Opera7.5 | Safari1.3 (MacOS X) |
IE5.2 (MacOS X) |
|
---|---|---|---|---|---|---|---|
document.all | ○ | ○ | × | △*1 | ○ | × | ○ |
document.getElementByTagName('*') | ○ | × | ○ | ○ | ○ | ○ | ○ |
NetscapeとSafariを捨てれば、document.allで大丈夫なのですが、普段使っているのがSafariなので捨てきれません。そうなると、ブラウザによる振り分け処理が必要です。このケースの振り分け処理は、ユーザエージェントを見る必要は無く、よく使われているdocument.allをチェックする方法を採用します。
マルチプラットフォーム対応コーディング
if(document.all){ myArray=document.all; } else { myArray=document.getElementsByTagName('*'); } for(ii=0; ii<myArray.length; ii++){ if(myArray[ii].className=='myClass'){ myArray[ii].style.display='none'; } }
新たな疑問
今回やった様に要素毎にstyle.displayを変更するのではなく、特定のClassセレクタの定義内容を変更することで、classが同じである全ての要素に変更を反映する方法は無いのでしょうか?ざっと検索してみたところ、それらしいものは見当たらなかったので、また時間のあるときに調べてみることにしましょう。
*1:Javascriptコンソールに警告が出る