* JavaScript メモ [#e3baac80]
JavaScript に関するメモを追記していく。

#contents

** IEとFirefoxの違い [#x07c8e64]
Firefoxの方が[[W3C勧告:http://www.asahi-net.or.jp/~SD5A-UCD/rec-html401j/cover.html]]に忠実なようだけど、IEのシェアもいまだに大きい以上は無視できない(事実上標準)。

- [[HTML 4.01仕様書:http://www.asahi-net.or.jp/~SD5A-UCD/rec-html401j/cover.html]]
- [[W3Cの仕様書等の文書の日本語訳集:http://www.w3.org/Consortium/Translation/Japanese]]
- [[Gecko - Wikipedia:http://ja.wikipedia.org/wiki/Gecko]]
- [[Trident - Wikipedia:http://ja.wikipedia.org/wiki/Trident_(%E3%83%AC%E3%82%A4%E3%82%A2%E3%82%A6%E3%83%88%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%B3)]]

*** DOM扱いの相違 [#yc1faec2]
相違点を追記していく。
- タグで囲まれる文字列(CDATA)を取得するには、Firefoxでは textContent、IEではinnerText。(nodeValue ならどちらでもOK)
- childNode のとり方が違う。Firefoxは空白ノードをカウントする。IEはカウントしない。&br;
参考-> [[DOM入門 子ノードの取得:http://www.ajaxtower.jp/dom/ini/index4.html]]


*** Script実装の相違 [#vb02ebae]
相違点を追記していく。
- inputタグなどの onchange イベントのタイミングが違うっぽい。&br;
これが気になる場合は onclick などで代替。
- IEのonclickなどでsubmitする場合は、最後に return false をしないと、ソケットエラー(Firefoxなら書かなくても大丈夫)。
- IEではタグに勝手にいろんな属性を追加できる(divタグにvalueをつけたりとか)が、Firefoxではそれを取得できないことがある。&br;
確実に拡張属性をとるなら、getAttribute()で。
- イベントを追加するには、IEはattachEvent()、FirefoxはaddEventListener()。

*** 参考 [#p96b97ab]
- [[一撃必殺JavaScript日本語リファレンス:http://www.openspc2.org/JavaScript/ref/]]
- [[Gecko DOM Reference:http://developer.mozilla.org/ja/docs/Gecko_DOM_Reference]]
- [[とほほのWWW入門:http://www.tohoho-web.com/]]
-- [[WWW入門:http://www.tohoho-web.com/www.htm]]
- [[JavaScriptist:http://javascriptist.net/]]

** IEでJavaScriptをデバッグ [#f3e1ab7a]
*** ブラウザの設定を有効にする [#o4253836]
IEの「インターネットオプション」->「詳細設定」タブを開いてその中の「ブラウズ」カテゴリから「スクリプトのデバッグを使用しない(Internet Explorer)」というチェックがあるので、このチェックを''外す''(デフォルトでチェックがONになっている)。

ただ、これは Microsoft Office がインストールされている必要があるかも?

*** Windows Script Debugger を使う [#c9c79368]
[[Windows Script Debugger:http://www.microsoft.com/downloads/details.aspx?displaylang=ja&FamilyID=e606e71f-ba7f-471e-a57d-f2216d81ec3d]] を使う。

- [[Windows Script Debugger:http://www.microsoft.com/downloads/details.aspx?displaylang=ja&FamilyID=e606e71f-ba7f-471e-a57d-f2216d81ec3d]]

** FirefoxでJavaScriptをデバッグ [#mbb0848f]
*** Firebug を使う(お勧め) [#obb0b3ec]
これはかなり使いやすい。まずは下記ページからアドオンをインスコ。

- [[Firebug:https://addons.mozilla.org/ja/firefox/addon/1843]]

「署名がありません」とかいわれるけど気にしない。

インストールされたらFirefoxを再起動。メニューの「ツール」に「Firebug」という項目が増えているのでここから「Open Firebug」を選択、「Enable Firebug」をクリックするとデバッグが開始される。ブラウザで動作を見ながらステップ実行できるので、非常にやりやすい。

*** JavaScript Debugger を使う [#z9083413]
これはRADのような画面でScriptを追うツール。画面で確認する必要がなく、シンタックスや処理内容だけデバッグすれば良いときはこちらが良いのかも。

- [[JavaScript Debugger:https://addons.mozilla.org/ja/firefox/addon/216?id=216&vid=512]]

** サンプル [#l215c6fa]

*** フォーカスが当たると文字が消える [#n99a79d3]

focusinput.js
#code(javascript){{
	function removeText(formName,elementName){
		var target = document.forms[formName].elements[elementName];
		if(target.value == target.defaultValue){
			target.value = "";
			target.style.color='#000000';
		}
	}

	function insertText(formName,elementName){
		var target = document.forms[formName].elements[elementName];
		if(target.value == target.defaultValue || target.value == ""){
			target.value = target.defaultValue;
			target.style.color='#999999';
		}
	}
}}

sample.html
#code(html){{
<html>
	<head>
		<title>sample</title>
		<script type="text/javascript" src="focusinput.js"></script>
	</head>
	<body>
		<form name="form1">
			<input type="text" size="50" onfocus="removeText(this.form.name,this.name);" onblur="insertText(this.form.name,this.name);" maxlength="256" value="入力してください" style="color: #999999;">
		</form>
	</body>
</html>
}}

*** submit でボタンを無効にする [#u116a839]
[[こちら:http://espion.just-size.jp/archives/05/220233057.html]]のを参考に、再表示で元に戻す処理も追加してみた。

#code(javascript){{
var DisableSubmit = {
	init: function() {
		this.addEvent(window, 'load', this.onLoad());
	},
	
	onLoad: function() {
		var self = this;
		return function () {
			for (var i = 0; i < document.forms.length; ++i) {
				var elements = document.forms[i].getElementsByTagName('input');
				if (!elements || elements.length == 0) {
					continue;
				}
				self.setDisable(elements, false);
				self.addEvent( document.forms[i], 'submit', self.onSetDisable(elements, true) );
			}
		}
	},

	setDisable: function(elements, flag) {
		for (var i = 0, element; element = elements[i]; i++) {
			if (element.type == 'submit') {
				element.disabled = flag;
			}
		}
	},
	
	onSetDisable: function(elements, flag) {
		var self = this;
		return function () {
			self.setDisable(elements, flag);
		}
	},
	
	onCancel: function() {
		var self = this;
		window.setTimeout(function() {
			for (var i = 0; i < document.forms.length; ++i) {
				var elements = document.forms[i].getElementsByTagName('input');
				if (!elements || elements.length == 0) {
					continue;
				}
				self.setDisable(elements, false);
			}
		}, 1000);
	},
	
	addEvent: function(element, type, event) {
		if(element.addEventListener) {
			element.addEventListener(type, event, false);
		} else if(element.attachEvent) {
			element.attachEvent('on'+type, event);
		} else {
			element['on'+type] = event;
		}
	},
	
	removeEvent: function(element, type, event) {
		if(element.removeEventListener) {
			element.removeEventListener(type, event, false);
		} else if(element.detachEvent) {
			element.detachEvent('on'+type, event);
		} else {
			element['on'+type] = event;
		}
	}
}

DisableSubmit.init();
}}

ただ、このままだと、submit後にページ遷移しないケース(問い合わせダイアログを開いてキャンセルした場合など)で
ボタンが無効なままなので、onCancel() で元に戻すようにする。

#code(javascript){{
function confirm_msg(msg) {
	if(window.confirm(msg)){ 
		return true;
	}
	if(DisableSubmit){
		DisableSubmit.onCancel();
	}
	return false;
}
}}

*** 選択文字列をタグで括る [#hc3fed74]

選択文字列の取得の仕方がFirefoxとIEとでちょっと違うので、やむを得ず判定を使う。

taginsert.js
#code(javascript){{
var isIE = (navigator.appName.toLowerCase().indexOf('internet explorer')+1?1:0);

function getAreaRange(obj) {
	var pos = new Object();
	if (isIE) {
		obj.focus();
		var range = document.selection.createRange();
		var clone = range.duplicate();
		clone.moveToElementText(obj);
		clone.setEndPoint( 'EndToEnd', range );
		pos.start = clone.text.length - range.text.length;
		pos.end = clone.text.length - range.text.length + range.text.length;
	} else if(window.getSelection()) {
		pos.start = obj.selectionStart;
		pos.end = obj.selectionEnd;
	}
	return pos;
}

function insertTag(textAreaId,tag_st,tag_ed) {
	//var target = document.forms[].elements[];
	//var target = window.opener.document.getElementById(textAreaName);
	var target = document.getElementById(textAreaId);
	if (target == null) 
		return;
	var pos = getAreaRange(target);
	var val = target.value;
	var range = val.slice(pos.start, pos.end);
	var beforeNode = val.slice(0, pos.start);
	var afterNode = val.slice(pos.end);
	var insertNode;
	if (range || pos.start != pos.end) {
		insertNode = '<' + tag_st + '>' + range + '</' + tag_ed + '>';
		target.value = beforeNode + insertNode + afterNode;
	} else if (pos.start == pos.end) {
		insertNode = '<' + tag_st + '>' + '</' + tag_ed + '>';
		target.value = beforeNode + insertNode + afterNode;
	}
}

function insertAnchor(textAreaId,url,target) {
	var tag_st = "a href=\"" + url + "\"";
	if (target != null && target != "")
		tag_st = tag_st + " target=\"" + target + "\"";
	var tag_ed = "a";
	insertTag(textAreaId, tag_st, tag_ed);
}
}}

以下は、idが"edit"というテキストエリアにタグを挿入する例。

#code(html){{
<script type="text/javascript">
function insertTest() {
	var url = document.frm.url.value;
	var tar = document.frm.target.value;
	insertAnchor('edit', url, tar);
}
</script>

<body>
	<form name="frm">
		<textarea id="edit"></textarea><br>
		<input type="text" name="url" size="50">
		<input type="text" name="target" size="12"><br>
		<input type="button" value="挿入" onclick="insertTest()">
	</form>
</body>
}}

-----
[[MLEXP. Wiki]]

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS