剥いだ布団とメモランダム.old

情報系のことをかいてゆく

押すと出現してもう一回押すと消えるアレ[Javascript][html]

webページを作ってる時にどうしてもアレを作らなきゃいけなくなってしまい、JSでゴリ押しした話。
絶対もっといいやり方あると思いつつ、メモ。

つくりたいもの

これです、これ。

で、作るときの条件が、

  • "メールアイコン"を押したら"折りたたむアイコン(いい言葉が思いつかん)"に変わる
  • メールフォーム表示時に更新ボタン押してもフォームは表示されたまんま
  • IE8以降*1、火狐最新版、クローム最新版、Opera最新版で作動する

っていう感じです。

ちなみに、JSは初心者なのであしからず。

どうすんの

色々調べてみたら、イベントハンドラとDOMとかいうのを使いこなせばいけるっぽい。

イベントハンドラってなに

他のプログラミングでも出てくるので概念自体は大丈夫そう。マウスのクリックやページのロードといった処理のきっかけ。

イベントハンドラ 内容
onClick クリックされた時
ondbclick ダブルクリックされた時
onmouseover マウスオーバーされた時
onkeydown キーが押された時
onkeyup 押されていたキーが上がった時
onkeypress キーが押されて上がった時
onload ページが読み込まれた時
onunload ページが読み込まれていない時
onchange フォームに変更がなされたとき
onsubmit フォームの送信アクションがなされた時

比較的ネーミングで分かる。これ以外にもイベントハンドラはあるんですが、使いそうなものだけピックアップです。

onClickなどはクリックする対象のHTMLの要素内インラインに記述してやれば大丈夫。*2

DOMってなに

Document Object Model は HTML と XML ドキュメントへの API です。これは、ドキュメントの構造的な表現、その内容を変更可能にすること、そして視覚的なプレゼンテーションを提供します。本質的には、ウェブページをスクリプト又はプログラミング言語と結合します。
ウェブ開発者がウェブページを操作及び作成するのに役立つ全てのプロパティ、メソッド、そしてイベントは、objects に組込まれています。(例えば、document オブジェクトはドキュメントそのもの、table オブジェクトは HTML テーブル要素を表すなど)。これらのオブジェクトは最新のウェブブラウザのスクリプティング言語を通してアクセス可能です。

DOM (Document Object Model) について - DOM | MDNより

要は、JSでHTMLをいじりやすいようにしたプラットフォームみたいなもんですかね。(違ってたらゴメンナサイ)
DOMで用意されたメソッドによって直接HTML要素を生成したり、変更したり、HTMLから情報を得たりすることができるわけですね。

ソースコード

<html>
<head>
</head>
<script>
<!--
function dispForm(arg){
	if (arg){
		document.getElementById("box").style.display="block";
		document.getElementById("dispimg1").style.display="none";
		document.getElementById("dispimg2").style.display="block";
	}else{
		document.getElementById("box").style.display="none";
		document.getElementById("dispimg1").style.display="block";
		document.getElementById("dispimg2").style.display="none";
		if (document.URL=="https://dl.dropboxusercontent.com/u/46632739/jstest.html#box"){
			dispForm(true);
		}
	}
}
-->
</script>
<body onLoad="dispForm(false)">
<h1>押すと出現してもう一回押すと消えるアレ</h1>
<a id="dispimg1" href="./jstest.html#box" onClick="dispForm(true)"><img src="./pic/mail.png"></a>
<a id="dispimg2" href="./jstest.html" onClick="dispForm(false)"><img src="./pic/arrow_up.png"></a>
<div id="box">
	<form id="mailform" method="post" action="">
		<table border="0" cellspacing="0" cellpadding="0">
			<tr>
				<td class="formtopic">氏名:</td>
				<td><input type="text" name="name" size="50" maxlengh="50"/></td>
			</tr>
			<tr>
				<td class="formtopic">所属:</td>
				<td><input type="text" name="attribute" size="50" maxlenghth="50" /></td>
			</tr>
			<tr>
				<td class="formtopic">メールアドレス:</td>
				<td><input type="text" name="e-mail" size="50" maxlength="50" /></td>
			<tr>
			</tr>
				<td colspan="2" class="formtopic">問い合わせ内容<br />
				<textarea name="request" cols="50" rows="5"></textarea></td>
			</tr>
		</table>
		<p><input type="submit" value="  送信  " /><input type="reset" value="  リセット  " /></p>
	</form>
</div>
<p>こんな感じです。Dropboxに上げているので少し鈍いですが。</p>
</body>
</html>

重要なのは、script要素の部分。
document.getElementById("ID名")で指定したIDの要素の内容をいじることができる。
さらに
document.getElementById("ID名").style.display()とすることで、特定要素のdisplay属性の内容を設定、と。

"none"で非表示、"block"で表示にできる。

今回作成したdisplay属性では、非表示にした部分を詰めて表示するようになっているが、
document.getElementById("ID名").style.visibility()で、詰めずに表示・非表示を行うこともできるみたい。
この場合のパラメータは"visiable"(表示)と"hidden"(非表示)となる。
例)document.getElementById("ID名").style.visibility("hidden")
これでレイアウトは変更せずに非表示となる。

あとは、

if (document.URL=="https://dl.dropboxusercontent.com/u/46632739/jstest.html#box"){
	dispForm(true);
}

の部分で、メールアイコンが押されたあとに更新がされても表示されるようにしてます。
#boxはメールアイコンクリック時のリンク先となっているので、メールフォームが表示されている時にはURLの末尾に#boxがつくようにしていることに注意です。
document.URLでは実行されたサイトのURLが得られるので、比較するときにはサイトのフルのURLを入れておきます。
相対パスじゃダメですよ!

雑感

webサイトのスクリプト周りはjQueryを適当にぶち込んでやっていたので、あー、こうやって作っていくのかという感じでした。
絶対他にいいやり方がありそう…

DOMのメソッドの使い方に慣れておけば、結構自分の作りたいものができそうな気がしてしまう感じがJSいやらしい。
また時間があるときになにか作ってみます。jQuery関係ももう少し勉強する必要がありそうです。

*1:って思ってたんだけど、IEだけ更新時の動作が上手くいきませんでした…

*2:分離して記述する方法の方が推奨されてるっぽいです