JavaScriptでランダムな#RRGGBBカラーを表示・出力させる

以前作ったWebベンチマークソフトはさすがに設計が古すぎたので修正中。 これはランダムな色を#RRGGBB形式で生成したいときに用いるJSライブラリである。幸い、ワンライナーで生成する方法があるようなので、ここに記しておく。

function random_rrggbb()
{
	return '#'+Math.random().toString(16).slice(-6);
}

最近のモダンブラウザであれば問題なく表示できる。 ただ、古いブラウザには、小数点以下を16進数で変換した場合0になる困った仕様のものがあったので、 確実に動作させたい場合は、小数点以上から生成するように修正する必要がある。

<script>

function random_rrggbb()
{
	return '#'+('00000'+(Math.random()*(1<<24)|0).toString(16)).slice(-6);
}

</script>

<form><input type="button" onClick="alert(random_rrggbb())" value="ランダム#RRGGBBを求める"></form>

コードを保存して実行するか、以下のボタンを押すと求めることができます。IE6以降、Netscape 4.8、Webkit(KHTML,Chromium)ベースブラウザ、Operaベースブラウザ、Netfront v4ベースブラウザで確認。

JavaScriptでUNIX Timeを求める
http://blog.livedoor.jp/mksaver70/archives/51473252.html

  

IE8 JavaScript-JSON.parseのStack overflow問題(KB976662)

いつかは使うかもしれません、JSON。このサンプルはKB976662適用前のIE8だとオブジェクトに何らかのArray.prototypeか、Object.prototypeを指定するとStack overflowを引き起こします。

<!DOCTYPE html>

<script>
window.onload = function() {

	if (!this.JSON) {
		alert("Please try IE8 Standard Mode!");
		return;
	}

	Array.prototype.proto = new Array(100,200,300);
	// Object.prototype.hoge = new Object;

	var arrays = "[10, 20, 30]";

	function reviver(a, b) { return b; }
	var obj = JSON.parse(arrays, reviver); // Stack overflow

	var s = ''; for (i in obj){ s += (i + " : " + obj[i] + "\n"); }
	
	alert(s);
}
</script>

適用前はこうなります。

---------------------------
Web ページからのメッセージ
---------------------------
Stack overflow at line: 17
---------------------------
OK   
---------------------------

適用後はこうなります。

---------------------------
Web ページからのメッセージ
---------------------------
0 : 10
1 : 20
2 : 30
proto : 100,200,300

---------------------------
OK   
---------------------------

更新プログラムは、Internet Explorer 8 では、ネイティブ JSON 機能です。
http://support.microsoft.com/kb/976662

  

Windows7のGPSセンサー(Location API)とGoogle Mapsを利用して今いる居場所を割り当てる(未検証)

Ubuntu 9.10とWindows 7が登場してOSいじくりが満足にできてうれしい毎日ですがみなさんいかがでしょうか。自分もWindows7 Pro UPG版を購入して、Ubuntuもマウスが効かないバグにはまりながらもようやくKarmicにアップデートいたしました。特にWindows 7については追加された機能が豊富すぎて訳分からん状態なのです。あとで自分なりにまとめたいですねえ。

Windows 7が提供する新機能の一つに「Location API」というものがあります。Windows ガジェットの「天気」にも、Location APIが使われている形跡が見られ、位置を自動的に検出するオプションがあるようです。GPSを持っていれば、移動中に自分が今いる場所の天気を表示できるというわけです。

位置を自動的に検出するオプション
こんなやつ。GPSは持ってないので恩恵は受けられないのですが…

このLocation APIをJavaScript(JScript)を利用して、GPSから緯度経度を抽出し、最終的にGoogle Mapsを呼び出して自分のいる場所を割り当てるサンプルを作ってみました。ただし、自分はGPSを持っていないのでどうなるかは分かりませんが、抽出された緯度、経度がNumber型であることを仮定した上で作成してしています。

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">

function loc_get(name0, name1)
{
	var loc0 = document.getElementById(name0);
	var loc1 = document.getElementById(name1);
	var list = [];

	list[list.length] = {};
	list[list.length-1].name = "緯度";
	try { list[list.length-1].value = loc0.LatLongReport.Latitude; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	list[list.length] = {};
	list[list.length-1].name = "経度";
	try { list[list.length-1].value = loc0.LatLongReport.Longitude; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	list[list.length] = {};
	list[list.length-1].name = "住所1";
	try { list[list.length-1].value = loc1.CivicAddressReport.AddressLine1;
	if(list[list.length-1].value == "") list[list.length-1].value = "測定できません"; }
	catch(e) { list[list.length-1].value = "測定できません"; }
	
	list[list.length] = {};
	list[list.length-1].name = "住所2";
	try { list[list.length-1].value = loc1.CivicAddressReport.AddressLine2;
	if(list[list.length-1].value == "") list[list.length-1].value = "測定できません"; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	list[list.length] = {};
	list[list.length-1].name = "国";
	try { list[list.length-1].value = loc1.CivicAddressReport.CountryRegion;
	if(list[list.length-1].value == "") list[list.length-1].value = "測定できません"; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	list[list.length] = {};
	list[list.length-1].name = "都道府県";
	try { list[list.length-1].value = loc1.CivicAddressReport.StateProvince;
	if(list[list.length-1].value == "") list[list.length-1].value = "測定できません"; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	list[list.length] = {};
	list[list.length-1].name = "市町村";
	try { list[list.length-1].value = loc1.CivicAddressReport.City;
	if(list[list.length-1].value == "") list[list.length-1].value = "測定できません"; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	list[list.length] = {};
	list[list.length-1].name = "郵便番号";
	try { list[list.length-1].value = loc1.CivicAddressReport.PostalCode;
	if(list[list.length-1].value == "") list[list.length-1].value = "測定できません"; }
	catch(e) { list[list.length-1].value = "測定できません"; }

	return list;
}

function init(name0, name1, name2, name3)
{
	if(!('\v'=='v')) {
		alert("IEじゃないと動きません。");
		return;
	}

	var loc0 = document.getElementById(name0);

	if(typeof(loc0.Status)=="undefined") {
		alert("Windows 7以降じゃないと動きません。");
		return;
	}

	switch(loc0.Status) {
		case 1:	
			alert("エラーが発生しました。");
			return;
		case 2:
			alert("アクセスは拒否されました。");
			return;
		case 3:
			alert("しばらく待ってから、もう一度押してください。");
			return;
		case 0:
			if(!confirm("サポートしてないようですが、ダメもとで測定してみますか?"))
			return;
		case 4:
			break;
		default:
			alert("この雰囲気…もしや新しいAPIかっ!?");
			return;
	}

	var list = loc_get(name0, name1);
	var str = "";
	var Lat;
	var Long;
	
	// 取得したものをHTMLに戻す
	for (i = 0, j = list.length; i < j; i++) {
		str += list[i].name + ": " + list[i].value + "<br>";
		if (list[i].name == "緯度") Lat = list[i].value;
		if (list[i].name == "経度") Long = list[i].value;
	}

	try { document.getElementById(name2).innerHTML = str; }
	catch(e) { alert(str.replace(/<br>/g,"\n")); }

	if(typeof(Lat) == "number" && typeof(Long) == "number") {
		document.getElementById(name3).src =
		"http://maps.google.com/maps?q=" + Lat + "," + Long +
		"&z=14&iwloc=near&output=embed";
		document.getElementById(name3).style.display = "";
	}

	return true;
}

</script>
</head>
<body>
<form>
<input type="button" onclick="init('loc0','loc1','div0','iframe0')" value="計測">
</form>
<!-- 緯度経度を調べるためのオブジェクト -->
<object id="loc0" width="0" height="0"
 classid="clsid:9DCC3CC8-8609-4863-BAD4-03601F4C65E8"></object>
<!-- 都道府県市町村を調べるためのオブジェクト -->
<object id="loc1" width="0" heihgt="0"
 classid="clsid:2A11F42C-3E81-4AD4-9CBE-45579D89671A"></object>

<!-- 表示に関わるもの -->
<div id="div0"></div>
<iframe id="iframe0" width="640" height="480" src="about:blank" style="display:none"></iframe>
</body>
</html>

動作条件として、Windows 7以降であること(多分)、要ActiveXなのでIEを使って動作させていること、そして、GPSを持っていること(自分は持ってないので検証できないという罠w)。GPSが無くてもWindows 7以降であれば強制的に動作させることも可能です。ただ、GPSがないと「国」だけしか分からないようです。

.html(できれば.htaで)を保存して、IEを立ち上げ、計測ボタンを押すとAPIが動作し、Google Mapsの矢印が表示されるという流れになっています。loc0.Statusが4になればGPSがあっても無くても準備はできたと判断できます。

緯度経度がどのようにWindowsから返されるのかが分からないです。多分Numberで返ってくるだろうと思いますが、0以上のNumberなら動く可能性が高いです。動作検証は自己責任でお願いします…

成功イメージ
うまくいけばこんな感じで動いてくれると思います

(2009.11.10)Sensor APIじゃなくてLocation APIの間違いだったので書き直し。詳しくはここを参照。
http://msdn.microsoft.com/en-us/library/dd464636(VS.85).aspx

  

XHTML2終了のお知らせ

XHTML 2 Working Group Expected to Stop Work End of 2009, W3C to Increase Resources on HTML 5
http://www.w3.org/News/2009#item119

XHTML の今後に関する FAQ
http://standards.mitsue.co.jp/resources/w3c/2009/06/xhtml-faq.html

<video>タグ等の登場でビデオやマルチメディアもとりあえず正式に扱えるようになるハイパーテキストVersion5。Firefox 3.5をインストールしていて、videoタグをいち早く試したい方はVideo Bayというサイトに行くことをお勧めします。ファイル形式は.ogg(Ogg Vorbis)だからOgg Vorbis対応ソフトをインストールしておけば、ファイルをダウンロードして見られないことはないのですけど。

ちなみに自分が言うのもアレですけど、このサイトはDOCTYPE宣言すらされてないです。きちんと記述する場合には、HTML 4.01 Strictで記述してます。まあそんなもんです。

The Video Bay - Extremly early test - HTML5 media tags
http://thevideobay.org/

  

JavaScriptでUNIX Timeを求める

1234567890記念。new Date()の中身はUNIXTIME & ミリ秒。なのでミリ秒の部分を切り落とすだけで計算できます。

<script>

function time_t()
{
	return new Date/1e3|0;
}

</script>

<form><input type="button" onClick="alert(time_t())" value="unix time"></form>

コードを保存して実行するか、ボタンを押すとUNIX TIMEが表示されます。Firefox1.0以降、IE6以降、Netscape 4.78、iモードHTMLシミュレータIIで確認

(2009.09.11)サンプルを用意しまして書き直しました。

(2010.04.13)書き直しました。

  

HTML+スピンボタン(IE ActiveX)+JavaScriptを動作させるメモ

最近目にしないActiveX Objectではあるが、このオブジェクトをJavaScriptで動作させる方法を調べた。以下のコードはスピンボタンのサンプルで、普通にブラウジングしているなら目にしないものだ。プルダウンとはまた違う。最近だとHTML 5で採用されるだとかされないだとか。表示させた後スピンボタンを押すと左のインプットエリアに結果が表示される。

<html>
<head>
<style>object { height: 1.2em; }</style>
<title>ActiveX SpinButton Test</title>
</head>
<body>
<input id="view" type="text" name="view" value="">

<object classid="CLSID:79176FB0-B7F2-11CE-97EF-00AA006D2776" 
	id="hoge" onchange="alert('!')">
	<param name="Min" value="-10"><!-- マイナスは使えない -->
	<param name="Max" value="100">
	<param name="Position" value="0">
</object>

<script type="text/javascript" for="hoge" event="change">
<!--//
	document.getElementById("view").value = this.value;
//-->
</script></body></html>

spinbutton

このobjectはスピンボタンである。属性classidは必ずCLSID:7917…でないとスピンボタンは出現しない。パラメータはMin(最小数値)、Max(最大数値)、Position(初期値)など。マイナス数値は使えない。入れたとしても必ず0になる。

注意したいのはJavaScriptの入れ方。Objectタグに属性onchange=(JavaScriptコード)というような記述の方法だと機能しないようだ。Scriptタグのfor属性にはオブジェクトのidを入れる。event属性は(on)changeで。また、Officeをインストールしないと動作しない。

参考
An OBJECT Example--Using a Spin Button
http://msdn2.microsoft.com/en-us/library/ms952594.aspx

  

JavaScriptの@cc_onでIEを区別

JavaScriptでIEかどうかをたったの1行で判別する方法
http://phpspot.org/blog/archives/2007/04/javascriptie1.html

考え付いた人はすげえな。それなら

<script>

var isIE = /*@cc_on!@*/0;
isIE ? alert("IE") : alert("other");

</script>

これでもいけるな

  

いじってみた

きょうはブログの設定を弄ってみた。
概観がちょっと変わっただけ。  

標準モードのIE6、IE7におけるCSS「white-space:pre」とinnerHTML

IEには互換モードと標準モードでレンダリングに差があるのは知ってますか?
この標準モードだけ動作するスタイルシートのwhite-space: preだけど
innerHTMLを使って文字を追加すると属性が無効になり、描画が崩れる。
確認できたのはIE6とIE7。Firefoxは問題ない。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 EN//"
 "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<script>
function test()
{
	document.getElementById("foo").innerHTML += "test";
}
</script>
</head><body>
<a href="javascript:test()">GO!</a>
<div id="foo" style="white-space: pre">
hoge1
hoge2
hoge3
</div>
</body></html>

色々検証してみた(予想)が、これは作成者がwhite-space: preを適用した場合IEは何をしているかというと、

何も適用していないHTML

hoge1\r\nhoge2\r\nhoge3\r\n
にwhite-space: preが指定されていたら、\r?\nを<br>に置き換えたものを表示するのだが、
innerHTMLには<br>を変換していない(あるいは\r?\nを抜いた状態の)HTMLを保持したままの状態なので、
innerHTMLを変更すると、<br>に変換していない状態のHTMLで描画してしまうということになる。

なんで<br>?という人はこのinnerHTMLをFormに投げてPOSTするとよく分かると思う。
この現象を回避するにはDOM動作でよく使用するappendChildを使う。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 EN//"
 "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<script>
function test()
{
	document.getElementById("foo").appendChild(
		document.createTextNode("test")
	);
}
</script>
</head><body>
<a href="javascript:test()">GO!</a>
<div id="foo" style="white-space: pre">
hoge1
hoge2
hoge3
</div>
</body></html>

こうすることで、描画が崩れることもなく文字が追加される。ただし、これは裏では

#text
#text
#text

…と#textを追加しているだけで、根本的解決法ではない点は注意。
<や>も&lt;というように変換されるし使えないかも。

  

HTA - JavaScript+IEを使ったWindowsアプリケーション

厳密にはJScript Version 5.0以降。XMLHttpRequestが注目され始めたけど、
JavaScriptを使ったWindownアプリケーション作れねーかなと思ったらこれ。HTA。

HTML Applicationの略らしい。
IE5.0から出てきた。
IE5.0はtry-catchが使える。document.getElementByIdが無条件に使える。
つーことはDOM対応。XML取得はXMLHTTPじゃなくて、Microsoft.XMLDOMで可(試してないけど)。
CSSもある程度使えるが、border-cssが使えず、結構厳しめ。
filter系はDirectX使わないやつなら対応。

HTA:APPLICATIONタグ
http://www.geocities.jp/kiaswebsite/hta/hta_application.html

では、簡単なやつ。

<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta http-equiv="Content-Style-Type" content="text/css">
<hta:application maximizeButton="no" scroll="no" innerBorder="no" 
contextMenu="no" border="dialog"></hta:application>
<style type="text/css"><!--
* { cursor: default; overflow: hidden; }
body { margin: 0px; padding: 0px; background: ThreeDFace; }
form { margin: 10px; }
input { width: 290px; height: 190px; font-size: 12pt; }
--></style>
<script type="text/javascript"><!--//<![CDATA[
window.resizeTo(320, 240);
//]]>--></script>
<title>HelloWorldApplication</title>
</head>
<body>
<form>
<input id="button1" type="button" value="Hello, World"
onclick="javascript:alert('Hello, World!')">
</form>
</body>
</html>

UTF-8形式、hogehoge.htaとファイル名にして、実行とな。
と、こんな感じに表示されたぞ。

ここでボタンを押すと、

IE5.0の時のHTAではinnerBorder="no"が適用されなかったり、
overflow: hiddenしないと、スクロールバーが出たりするんで注意。
あとHTAの部品はIEの文字サイズに依存するのでこれも注意。

いやはや、これは簡単。
windows.hなんか知らねーけど、JavaScriptなら使えるゼという粋な方には、オススメ。
デメリットは遅い、ソースが常にオープンだけど、手軽に作れるので、オススメ。