checkboxの表示



0   名前: 初心者aisuke : 2006/07/19(水) 21:59  ID:RjOL/xyL
はじめまして だいすけ といいます。
今回、下記のような問題点が解決出来ず皆様のお力を借りたいと思い
書き込ませていただきました。
よろしくお願いします。

<HTML>
<HEAD>
<SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript"> 
<!-- 
var x; 
function a(){
	 x = "<input type='checkbox' value='a'>動物です";
	 b()
}
//--> 
</SCRIPT> 
</HEAD>
<BODY> 
<form name="frm">
	<SELECT NAME="animal" onchange="a()">
		<OPTION VALUE="00">犬
		<OPTION VALUE="01">ネコ
	</SELECT>

<script language = "javascript">
function b(){
	document.write(x);
}
</script>
<form>
</BODY>
</HTML> 

このような形で変数Xを使いチェックボックスを作成したいのですが作成されたときにチェックボックス以外
消えてしまいます。
このようにbodyタグの中でfunctionを呼びチェックボックスを作成してもHTML全体が表示されるような方法
はあるのでしょうか?
最終的にはリストで選択されるたび変数Xに入れる内容を変えさまざまなチェックボックスを作成したいと考
えています。
もしよろしければご回答のほどお願いします。

1   名前: 牛若 : 2006/07/19(水) 21:59  ID:NIXhe6Co
document.writeを使っていれば当然ですね。
これを解決するには、DOMで目的のオブジェクトに要素を追加する方法が一般的です。
appendChild()などお勉強されることをお勧めします。

2   名前: 初心者aisuke : 2006/07/19(水) 21:59  ID:DcyeX7.b
牛若さんありがとうございます。
DOM、appendChild()は初めて耳にする言葉です。。
まだまだ勉強不足でした。
これから色々なサイトをまわって勉強しようとおもいます。

3   名前: 匿名 : 2006/07/19(水) 21:59  ID:DcyeX7.b
<script type="text/javascript"><!--
function create() {
var divObj = document.getElementById("pBox");
var chObj = document.createElement("input");
chObj.setAttribute("type","checkbox");
divObj.appendChild(chObj);
}
// --></script>
</head>
<body>
<form>
<input type="button" id="myButton" value="Click" onClick="create()">
</form>
<div id=pBox></div>
</body>

チェックボックスを作る所までは出来たのですが
□イヌ
□ネコ
といったようにチェックボックスの横にラベルを表示させ、改行させるような方法を探して
いるのですがもしよろしければ皆様のお力をお貸しください。
あと一度作られたチェックボックスを消して新たに作り直すというようなこともできるので
しょうか?

4   名前: NullPo : 2006/07/19(水) 21:59  ID:XoE1slt9
>>3
ラベルがどんなもんを想像しているかわからないけど、以下のような感じで似たことができるかな。
削除はdiv要素ごと消してるけど、同じ方法でチェックボックスも消せるので適当に変更してください。

function create()
{
  var newDiv = document.createElement("div");
  var oldDiv = document.getElementById("pBox");
  var chArray = ["いぬ", "ねこ"];

  if(oldDiv != null)
    oldDiv.parentNode.removeChild(oldDiv);
  document.getElementsByTagName("body")[0].appendChild(newDiv);
  newDiv.setAttribute("id", "pBox");

  for(var ix = 0; ix < chArray.length; ix++)
  {
    var chObj = document.createElement("input");
    var textObj = document.createTextNode(chArray[ix]);
    var brObj = document.createElement("br");

    chObj.setAttribute("type", "checkbox");

    newDiv.appendChild(chObj);
    newDiv.appendChild(textObj);
    newDiv.appendChild(brObj);
  }
}


5   名前: Pid : 2006/07/19(水) 21:59  ID:PC1xIR5b
念のため。
http://chaichan.hp.infoseek.co.jp/qa5500/qa5840.htm

あと,DOM HTML が使える環境なら,わざわざ setAttribute する必要はないです(XML 文書を扱う場合は必須ですが,こと HTML 文書を扱う場合に限っては,setAttribute の実装に不具合を抱える実装の方がまだ多いです)。

6   名前: 初心者aisuke : 2006/07/19(水) 21:59  ID:RjOL/xyL
牛若さん、NullPoさん、Pidさん、貴重なお時間を使っていただきありがとうございます。
皆様の意見を参考にしてプログラミングしていきたいと思います。
完成の際(完成できればですが・・・^^;)にはソースを記載しますので問題点などを指摘し
ていただければうれしく思います。
最後にPidさんのsetAttributeを使わない方法というのがいまいち掴みきれませんでした、
他に記述方法があるということなのでしょうか?
探しては見たもののsetAttributeが使われているソースしか見当たらずどれがそれにあたるのかも理解できません。
せっかくのご意見に質問をぶつけるのは大変失礼と思いますが、もしよろしければ簡単な説明でもいいのでお願いいたします。

7   名前: NullPo : 2006/07/19(水) 21:59  ID:1Bb3RL38
5はcheckのやつかぁ、昔どうしてチェックが付かないんだろうと思ってました。
chObj.defaultChecked = true;
ってので対応してましたが、IE6、FireFox、Operaで動きました。

>setAttributeを使わない
私が思いつくのは
chObj.type = "checkbox";
くらいかな。

8   名前: Pid : 2006/07/19(水) 21:59  ID:fpWKjEXO
>>6
> 他に記述方法があるということなのでしょうか?

すでに >>7 で NullPo さんが書いて下さいましたが,

// DOM Core(基本モジュール)な方法
newDiv.setAttribute ('id', 'pBox');
chObj.setAttribute ('type', 'checkbox');

// DOM HTML(HTML に特化したモジュール)な方法
newDiv.id = 'pBox';
chObj.type = 'checkbox';


HTML 文書を扱う場合は,どちらでも構いません。ブラウザの DOM 実装であれば,ほぼ確実に DOM HTML をサポートしているはずです。



----

以下は参考までに。

ただし,DOM HTML は,あくまでレガシーな HTML 文書(HTML 4.01/XHTML 1.0)のために,かつての Dynamic HTML との互換性を重視したモジュールです。特に,オブジェクトのプロパティとして属性にアクセスする方法には汎用性がなく,推奨されていません(この意味では,>>3-4 で setAttribute を選択したのは適切な判断でした)。
http://www2u.biglobe.ne.jp/%7Eoz-07ams/prog/dom-ref/HTML/#ID-642250288-h3

しかしそれでも,私が HTML 文書での setAttribute を避けたがるのは,次の理由からです。

・歴史的な理由により,各ブラウザの setAttribute の実装には問題がつきまとっていること(IE,Mozilla,Opera,Safari それぞれで微妙な問題がある)。

・モデルを熟知しないと「変だな?」という事態になることが多い(特に,setAttribute ('style', ..) や setAttribute ('onclick', ..) という書き方は,文法にうるさい HTML マニアなら (^^;) 違和感あるいは躊躇を感じるでしょうが,うっかり書いてしまいがち)。

そういうわけで,慣れるまでは DOM HTML(+ JavaScript 1.3?)を使った方が良いかな,と「現時点では」私は考えています。XML 文書を扱うときに setAttribute を思い出せば,まずは十分でしょう(で,徐々に setAttribute に移行していく,と)。

9   名前: Pid : 2006/07/19(水) 21:59  ID:fpWKjEXO
あと >>5 でも少し触れましたが,IE(WinIE も MacIE も)の input 要素生成にまつわる挙動不審さは馬鹿にできません。

MacIE: DOM による要素生成後にクラッシュすることがある
http://cssbug.at.infoseek.co.jp/detail/macie/b040.html

WinIE: createElement に属性付きタグを放り込む方法
http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/createelement.asp
http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/name_2.asp

もしかすると今回のケースでは,(非公式かつ安全でないにしろ)innerHTML でガリガリ書いた方が無難かもしれません。


----

まあそんなことはともかく,まずは一度作ってみて下さいな。

10   名前: 初心者aisuke : 2006/07/19(水) 21:59  ID:RjOL/xyL
<script language="JavaScript">
<!--
	var k1_Array = new Array(0); 
		k1_Array[0] = ["1","海の生物"];
		k1_Array[1] = ["2","山の生物"];
				
	var k2_Array = new Array(0);
		k2_Array[0] = ["1","1","魚類"];
		k2_Array[1] = ["2","1","哺乳類"];
		k2_Array[2] = ["3","2","爬虫類"];

	var k3_Array = new Array(0);
		k3_Array[0] = ["1","1","1","サメ"];
		k3_Array[1] = ["2","1","1","マグロ"];
		k3_Array[2] = ["3","1","2","イルカ"];
		k3_Array[3] = ["4","1","2","クジラ"];
		k3_Array[4] = ["5","2","3","ヘビ"];
		k3_Array[5] = ["6","2","3","トカゲ"];
		
		var newDiv = document.createElement("div");
		

		
function load(){
	for(var i=0; i<k1_Array.length; i++){
		document.frm.k1.options.length = k1_Array.length;
		document.frm.k1.options[i].text = k1_Array[i][1];
		document.frm.k1.options[i].value = k1_Array[i][0];
	}

	var count = 1;
	for(var i=0; i<k2_Array.length; i++){
		if(k2_Array[i][1] == 1){
			document.frm.k2.options.length = count;
			document.frm.k2.options[count-1].text = k2_Array[i][2];
			document.frm.k2.options[count-1].value = k2_Array[i][0];
			count++;
		}
	}
		
		  document.getElementById("ch").appendChild(newDiv);
 		  newDiv.id="ch";
	for(var i=0;i<k3_Array.length; i++){
		if(k3_Array[i][1]==1 && k3_Array[i][2]==1){
			var chObj = document.createElement("input");
   			var textObj = document.createTextNode(k3_Array[i][3]);
    		var brObj = document.createElement("br");
    		
    		chObj.type="checkbox";
		    newDiv.appendChild(chObj);
		    newDiv.appendChild(textObj);
		    newDiv.appendChild(brObj);
		 }
	}	
}
function k1_ch(){
	var k1_val = document.frm.k1.value;
	count = 1;
	for(var i=0; i<k2_Array.length; i++){
		if(k2_Array[i][1] == k1_val){
			document.frm.k2.options.length = count;
			document.frm.k2.options[count-1].text = k2_Array[i][2];
			document.frm.k2.options[count-1].value = k2_Array[i][0];
			count++;
		}
	}
	
    var oldDiv = document.getElementById("ch");
    	if(oldDiv != null){
			oldDiv.parentNode.removeChild(oldDiv);
		}
	
	newDiv = document.createElement("div");
	document.getElementById("ch").appendChild(newDiv);
    	newDiv.id="ch";
	
	for(var i=0; i<k3_Array.length; i++){
		if(k3_Array[i][1] == k1_val && k3_Array[i][2] == document.frm.k2.options[0].value){
			var chObj = document.createElement("input");
   			var textObj = document.createTextNode(k3_Array[i][3]);
    		var brObj = document.createElement("br");
    		
    		chObj.type="checkbox";
		    newDiv.appendChild(chObj);
		    newDiv.appendChild(textObj);
		    newDiv.appendChild(brObj);
		}
	}
}
// -->
</script>
</head>
<body onload="load()">
<form name ="frm">
	<select name="k1" onchange="k1_ch()">
	</select>
	<select name="k2">
	</select>
	<div id="ch"></div>
</form>
</body>


11   名前: 初心者aisuke : 2006/07/19(水) 21:59  ID:RjOL/xyL
連続しての書き込みすみません。
上のソースが今の状況です。(エラー有りです)
チェックボックスを消したあと、同じ場所(div id="ch")にチェックボックスを作ろうとしていますが苦戦中です。
oldDiv.parentNode.removeChild(oldDiv)はdivそのものを消しているのでしょうか?
divを残したままreplaceChild()でチェックボックスを交換する事が出来るかと思いましたが
形にすることが出来ませんでした。
もしよろしければアドバイスをお願いします。

12   名前: 牛若 : 2006/07/19(水) 21:59  ID:I1x1Zny3
>oldDiv.parentNode.removeChild(oldDiv)はdivそのものを消しているのでしょうか?

そうなりますね。

>divを残したままreplaceChild()でチェックボックスを交換する事が出来るかと思い
ましたが形にすることが出来ませんでした。

オブジェクトを除去してしまった以上、そこにアクセスしようとすれば、帰ってくる答
えは「オブジェクトがありません」ですよね。
だから、肝心のオブジェクトを残して消せばよいわけです。なので、そのIDを持つオブ
ジェクトの子供(たち)を消せばよいのでは?ここでは、次のようにすればOKかと
(untested)
    var oldDiv = document.getElementById("ch").firstChild;
    	if(oldDiv != null){
               oldDiv.parentNode.removeChild(oldDiv);
		}

13   名前: 初心者aisuke : 2006/07/19(水) 21:59  ID:RjOL/xyL
牛若さんありがとうございます。
オブジェクトの指定先を子ノードにしてあげればよかったのですね。
IDを持つオブジェクトを全て参照出来るとは思いもよりませんでした。
牛若さん、NullPoさん、Pidさんには本当に助けられてばっかりですみません。
こうやって形にすることが出来たので本当に感謝しています。

まだまだソースに甘いところが多々あると思いますのでもしよろしければ指摘してくれると嬉しく思います。
(プルダウンもチェックボックスのようにしたかったのですが、方法がまだ見つからず現状を早く皆様に見てもらおうと思い、今の形で作りました。)

DOMで参考にさせてもらったサイトです
http://www.openspc2.org/JavaScript/JavaScript_DOM/

14   名前: Pid : 2006/07/19(水) 21:59  ID:5RkuFYu.
やあ,口うるさい爺やがやって来ましたよ。

> <script language="JavaScript">

script 要素の language 属性は HTML 4.0(1) で廃止予定となり,type 属性が必須となりました。「JavaScript 1.2 を特に使いたい」などの特別な理由がない限り,もう language 属性は使わないで下さい。

> var k1_Array = new Array(0);

Array に引数を与えるなら,配列の個数を与えた方がメモリの節約になります。でなければ,特に引数は要らないでしょう。

> document.frm.k1.options[i].text = k1_Array[i][1];

公式には,options[n].text は読み取り専用です。
http://www2u.biglobe.ne.jp/%7Eoz-07ams/prog/dom-ref/HTML/HTMLOptionElement.html#HTMLOptionElement-text
IE の場合は書き込み可能と MSDN に明記されていますが,他のブラウザを考慮に入れるなら,面倒でもテキストノードを appendChild して下さい。

また,いちいち document から辿るのは無駄ですので(塵も積もれば速度に関わるので),たとえば var opts = document.frm.k1.options; のようにして,オブジェクトへの参照を作成しておくと良いでしょう。

それから,load 関数と k1_ch 関数の内容には重複がありますので,たぶんまとめることができるでしょう。変数 count の var 宣言を忘れずに。

> <form name ="frm">

form 要素の name 属性は HTML 4.01 で非推奨となりました。id 属性を使って下さい(HTML 4.01/XHTML 1.0 ならば,両方併記しておくのが互換性のためにも望ましい)。と言いますか,実際のところ onchange で this.form を引数で渡せば,form 要素にラベルを付ける必要すらないのです(過去ログを参照して下さい)。

うるさく言ってすみませんでした。頑張って下さい。


----

おまけ。

> </head>

head 要素の終了タグがあるのに開始タグがないとはこれいかに。いや実は HTML 4.01 ならば「正しい」のですが,ならばきちんと文書型宣言で HTML のバージョンを明示しましょう。

15   名前: Pid : 2006/07/19(水) 21:59  ID:hG54nJl6
>>14
> form 要素の name 属性は HTML 4.01 で非推奨となりました。

ごめんなさい大嘘こきました。非推奨になったのは XHTML 1.0 からです。
http://www.asahi-net.or.jp/%7Esd5a-ucd/rec-html401j/interact/forms.html#adef-name-FORM
http://www.doraneko.org/webauth/xhtml10/20000126/Overview.html#h-4.10

とにかく,

<!-- 引数として select 要素ノード自身を渡す -->
<select name="k1" onchange="k1_ch(this)">

<!-- 引数として select 要素が属する form 要素を渡す -->
<select name="k1" onchange="k1_ch(this.form)">


のように JavaScript 1.1 の時代から書けるはずなので,複数の form 要素をまたぐデータのやり取りをするのでなければ,form 要素にラベルを付ける必要は(あんまり)ないのです。



----

あと,本当に細かいことなのですが,

> if(k2_Array[i][1] == 1)

k2_Array[i][1] は数字(String)ですよね。もちろん,比較の際に暗黙の型変換が適用されるので,問題は生じません。
http://www2u.biglobe.ne.jp/%7Eoz-07ams/prog/ecma262r3/11_Expressions.html#section-11.9.3

ただ,DOM インタフェース自体はかなり強い型付けで定義されていますから,DOM をお使いになる場合,数字(String)と数値(Number)の違いはできるだけ意識した方が良いでしょう(型付けの弱い JavaScript で型を意識しろというのも無茶な注文なのですが,そうしないと思わぬバグを招きやすいので)。

16   名前: 初心者aisuke : 2006/07/19(水) 21:59  ID:RjOL/xyL
Pidさん 数々の指摘、リンクまで張っての説明ありがとうございます。本当に感謝しています。
口うるさいなんてとんでもないです^^;
最初の頃にくらべると少しは進歩している気がします。これも皆様のおかげです。
現在リストボックスを同じように作成中です。
気になっていますのが(一部抜粋です)

var sel_1 = document.createElement("select");
    sel_1.name="k1";
    sel_1.onchange="k1_load()";  //記述方法はあっているでしょうか?
var newCh1 = document.getElementById("ch1").appendChild(sel_1);

for(var i=0; i<k1_Array.length; i++){
    	var chObj1 = document.createElement("option");
    	  chObj1.value=k1_Array[i][0];
    	var textObj1 = document.createTextNode(k1_Array[i][1]);
    	  sel_1.appendChild(chObj1);
	  chObj1.appendChild(textObj1);
}

var k1_val = sel_1.childNodes[0].firstChild.Value;
            //一番上に表示されているリストボックスのValue値はこれでもってこれるんでしょうか?

同じ記述でもif文の中にあるだけで参照できなかったりするので(記述ミスかもしれませんが)少しまた停滞気味です。
やはりvar 宣言はif文の中に書かないほうがよかったりしますか?
質問内容がタイトルと食い違ってきてますがやはり新しくスレッドを作り直すべきですか?

17   名前: Pid : 2006/07/19(水) 21:59  ID:Gt/TlD52
もう解決されたかもしれませんが,

> sel_1.onchange="k1_load()";
> //記述方法はあっているでしょうか?

気持ちはよく分かるのですが,そのような書き方は存在しません(少なくとも保証されたものではありません)。

sel_1.onchange = k1_load;

// 引数が必要なら(k1_load 関数内の this 値が変わるので注意)
sel_1.onchange = function () { k1_load (this); };


上記は古い JavaScript 1.2(だったっけ…?)の書き方ですが,ほとんどのブラウザがサポートしています。DOM Level 2 Events,MSIE DHTML Behavior を用いたより新しい方法については,過去ログを "addEventListener" などで検索してみて下さい。


> var k1_val = sel_1.childNodes[0].firstChild.Value;
> //一番上に表示されているリストボックスのValue値はこれでもってこれるんでしょうか?

firstChild が 2 回繰り返されてますが,階層関係は大丈夫ですか。

今回の場合,sel_1 は select 要素ノードですから,sel_1.options[0].value で値を取れますし,この方が簡単でしょう。


> var 宣言はif文の中に書かないほうがよかったりしますか?

んなこたーないので安心して下さい(関数宣言はダメですが)。

一覧へ戻る