ブラウザ依存の悩み


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標準では推奨しておらず、NetscapeSafariでは使用できません。(FirefoxOperaは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('*') ×

NetscapeSafariを捨てれば、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コンソールに警告が出る

2回じゃ足りない


Javascriptに関する質問に回答しました。
http://www.hatena.ne.jp/1124186363


1回目の回答に対するコメントに応答する形で、2回目の回答をしたのですが、質問者の方が満足できる回答ではなかった様なので、更に補足説明がしたいです。でも、3回目の回答は出来ません。
質問が終了する前に、トラッックバックしたら、質問者に伝わるでしょうか?とりあえずやってみます。

質問概要

1)任意のサイズの画像を別ウィンドウで表示し、ウインドウサイズを画像に合わせたい。
2)画像のサイズが確実に反映できる様に、画像の読み込み完了を待って、ウィンドウサイズを変更する。



Javascript Source

var objWin;
var timerID;

function fitimg() {
  myImage = objWin.document.getElementById('myImage');

  if (myImage.complete==undefined || myImage.complete) {  
    clearInterval(timerID); 
 
    w=myImage.width;
    h=myImage.height; 
 
    ua=navigator.userAgent;
   
    if(ua.indexOf("Firefox",0)>=0) {
      objWin.innerWidth=w;
      objWin.innerHeight=h;
    } else if(ua.indexOf("MSIE",0)>=0) {
      objWin.resizeTo(w,h);
      objWin.resizeBy(w-objWin.document.body.clientWidth,
              h-objWin.document.body.clientHeight-16);
    } 

    objWin.document.close();
  }
}

function popup(url){
  objWin=window.open("","myWindow","width=640,height=480");

  objWin.document.open();
  objWin.document.write("<html><head><title>サイト名</title></head>");
  objWin.document.write("<body style='margin:0; padding:0;'>");
  objWin.document.write("<img src='"+url+"' id='myImage'>");
  objWin.document.write("</body></html>");

  timerID=setInterval('fitimg()', 100);
}


解説

function popup(url)

ウィンドウをオープンして、指定されたurlの画像を表示。
Imageオブジェクトを識別するため、imgタグに、id属性を指定。
ウィンドウサイズを変更する処理fitimg()を、100/1000秒間隔で起動。

function fitimg()

id='myImage'で識別できるImageオブジェクトを取得。
対象のImageオブジェクトが読み込み完了(complete)であれば、以下の処理。
・インターバルをクリア
・ブラウザを区別して、ウィンドウのリサイズ処理(とりあえずFirefoxIESafariは不可)
・ドキュメントをクローズ

Windowサイズについて

resizeTo()は、Windowの外側のサイズを指定するので、画像サイズに合わせるには内側のサイズを指定する必要がある。
FirefoxではinnerWidth/innerHeightを使用。
IEでは、一度resizeToし、document.body.clientWidth/clientHeightで内側のサイズを参照して、外と内の差をresizeBy()で設定し直す。