Browsing the archives for the javascript category

JSEclipseのインスコ手順

Eclipse上でJavaScriptをきれいに表示して編集しやすい感じにしてくれるプラグインです。
JSEclipse

昔はここにいって簡単にDLできたんですが今日いってみるとなんか提供形式がかわってたのか簡単に落とせなかったのでメモ

Eclipse>help>Install New SoftWare

Work withのテキスト入力欄に

http://download.macromedia.com/pub/labs/jseclipse/autoinstall


を記入でエンター

するとリストにAjaxがでてくるからチェックつけてひたすらNextとか同意すればおk

ちなみに僕の環境は以下のとおり
Eclipse IDE for C/C++ Developpers
OS:WondowsVista

No Comments
5月 29, 2010 in javascript

Google maps api V3 を使ってみた。

Google maps apiを最近触ってみたんですが、やり始めがV2でAPIキーが必要とかで色々めんどくさかったんです。

一年前からgoogle maps api v3の登場をちらほらと聞いてはいたのでこれを機にとおもって使ってみた。
とはいったもののあまり参考になるサイトで日本語のものがないんですね。
困ったなぁとおもいながら英語のドキュメント読もうかとおもったら非公認の日本語ドキュメント発見

Google Maps API Version3 日本語ドキュメント(非公式)

らっきー! っておもってたら各オブジェクトの関数説明のところがちらほら「不明」とある。
翻訳がまだ完璧じゃないのかなっておもったら公式の英語ドキュメントですら空欄になってた。
未実装なんだろうか・・
とりあえずgoogle maps api v3の日本語ドキュメントを読みながらがんばってみた。

つくったものはこれです。
google_maps_api_v3

作ったシステムの仕様は以下のとおり。

—動作概要—
ページに地図を表示し、地図内の任意の場所にクリックでマーカーを設置することができ、そのマーカーが位置座標を返してくれるってもの。
マーカーはドラッグで位置変更可能。 
ダブルクリックでも移動してくれる。
——————-

あまり必要性はなかったかもしれないけど今回もjQuery使ってます。
なのでこのソースそのまま使いたい場合はjQueryダウンロードしてgoogle_map_v3.jsより手前でインクルードしといてください。

gmap_v3.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="jquery.js" ></script>
<script type="text/javascript" src="google_map_v3.js"></script>
<title>Google Maps V3</title>
</head>

<body>
<h1>地図上の座標取得ぷろぐらむ</h1>
任意の場所をクリックするとマーカーがあらわれます。 マーカーが位置とってくれます。<br/>
<div id="maps" style="width:500px; height:500px; border:1px solid #333;"></div>
<div id="flag">true</div>

<p>
	<h3>マーカーの座標(単位:緯度経度)</h3><br/>
	x座標 : <span id="x">地図上でクリックしてください。</span><br/>
	y座標 : <span id="y">地図上でクリックしてください。</span>
</p>
</body>
</html>

google_map_v3.js

$(function(){

	var marker;

    var mapdiv = document.getElementById('maps');
    var myOptions = {
        zoom: 5,//縮尺
        center: new google.maps.LatLng(38.680816,138.767537),
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        disableDoubleClickZoom : true,
        scaleControl: true,
        scrollwheel: true
    };
    var map = new google.maps.Map(mapdiv, myOptions);

    google.maps.event.addListener(map,'click',function(event){

    	if($("#flag").text()=="true"){

			var x = event.latLng.lat();
    		var y = event.latLng.lng();

			marker = createMarker(map,x,y);

    		$("#flag").text("false");

    		echoPoint(event.latLng);
    	}
    });    

});

function createMarker(map,x,y){
	 var marker = new google.maps.Marker({
		position: new google.maps.LatLng(x,y),
    	map: map,
    	title: "マーカーのタイトル",
    	draggable: true //なんかV3での動作が超遅いきがする
	 });

    google.maps.event.addListener(marker,'mouseup',function(){
    	echoPoint(marker.position);
    });		 

    google.maps.event.addListener(map,'dblclick',function(event){
    	marker.setPosition(event.latLng);
    	echoPoint(marker.position);
    });  

	return marker;

}

function echoPoint(point){

	var y = point.lat();
	var x = point.lng();

	$("#x").text(x);

	$("#y").text(y);

}

[解説]

gmap_v3.html

05行目
Google maps api v3のインクルードです。

06行目
jQueryをインクルードしてます。

07行目
今回作ったjsファイルをインクルードしてます。

14行目
このDiv要素に地図を流し込みます。 idでmapsを割り振ってます。 どうもサイズ指定したげないとGoogleさんが怒って変な表示にするみたいなんでスタイルシートいれて指定してます。

15行目
後述しますが、マーカーの表示処理の分岐に使います。

19/20行目
ここに緯度経度が表示されます。

google_map_v3.js

01~31行目
$(function(){
//処理
});
jQueryの書き方なんですが要するにgmap_v3.htmの読み込みが終わったらここに書かれた処理をするよってことです。

14行目
var map = new google.maps.Map(mapdiv, myOptions);

これでマップがでます。
MAPクラスのインスタンス化にmapdiv,myOptionsの二つの引数つけてますが、mapdivってのがgmap_v3.htmlの14行目に指定した地図を流し込むdiv要素になります。 型はHTMLコンテナでブロック要素なら多分なんでもおkです。
05行目のvar mapdiv = document.getElementById(‘maps’);でHTMLコンテナを取得してます。

mapOptionsが地図に付加されるオプションです。
ここでは

zoom: 5,
center: new google.maps.LatLng(38.680816,138.767537),
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDoubleClickZoom : true,
scaleControl: true,
scrollwheel: true

としてます。
上から3つまでが必須項目です。

zoomは地図の初期ズーム値です。 指定する数字が若いと縮尺がでかくなります。その逆もしかり。

centerは地図の中心座標です。 指定の型はLatLngっていうGoogleさんの提供してくれてるオブジェクトでこのオブジェクトを作るときの引数が緯度経度になります。 今はとりあえず日本がみれるような座標にしてます。

mapTypeIdはどんな地図にするかってもので今回はロードマップを使いたかったのでgoogle.maps.MapTypeId.ROADMAPと指定しています。

disableDoubleClickZoom : true,
ダブルクリックでのズームはオフにしてます。 うざいよねこれ。

scaleControl: true,
地図のコントロールバーを表示してます。

scrollwheel: true
マウスのスクロールホイールで縮尺を変更できるようにしてます。

16行目
イベントリスナの登録です。
google maps上でのイベントの登録はaddListenerで行います。
引数は
1.イベントが発生するオブジェクト
2.イベントの種類
3.処理(関数)

これは地図上をクリックした時の処理について記述しているので第一引数にMapオブジェクトのはいってるmap、第二引数にclickを指定しています。
第三引数は処理関数です。
clickイベントのときはマウスイベントオブジェクトが関数の引数として指定できます。
マウスイベントオブジェクトは以下の二つのプロパティを持ってます。
latLng ….前述のとおり緯度経度を含むオブジェクトです。
pixel ….これまたGoogleさんの作ったオブジェクトでPointオブジェクトというものです。 これはイベントが発生した位置のカーソルのピクセル値を返します。

18行目if
手前のaddListnerが地図をクリックしたときにマーカーを表示するっていう目的のものなんだけど、クリックするたびにマーカーがどんどんでてきたらマーカーだらけになるので初めてのクリックだけにマーカーを出すというための条件分岐です。

gmap_v3.htmlの15行目のdivの中身がtrueだったら~という分岐です。
ちなみにマーカーが入ったと同時に25行目の$(“#flag”).text(“false”);という処理でdivの中身がfalseにかわるのでこの分岐は一度しか適応されません。

20/21行目
マウスイベントオブジェクトのプロパティであるlatLngオブジェクトのメソッドlat()で緯度をlng()で経度を取得してそれぞれを変数x,yにいれてます。

23行目
createMarker(map,x,y);でマーカーを作ってます。
このcreateMarkerは僕の定義した関数で33行目のところの関数です。

google.maps.Marker({});でマーカーをインスタンス化してます。
地図同様にオプションが指定できます。
positionがマーカーを設置する緯度、経度でLatLngオブジェクトで指定します。
mapはマーカーを設置するマップオブジェクトを指定します。
titleはマーカーのタイトル
draggableはマーカーがドラッグで移動できるかどうかをbool値で指定できます。

41/45行目
前述のaddListenerを使ってマーカーのmouseupイベント、マップにdblclickイベント時に座標を出力するようにイベント処理を登録してます。
mouseupイベントはマーカーをドラッグしてるとき、ドラッグをやめた瞬間に発生するイベントです。 
dblclickはダブルクリック時に発生します。
これは第三引数の関数に対してまた、マウスイベントオブジェクトを与えることができます。

mouseupのときとdblclickの時の両方で行ってるのがechoPoint関数でこれは引数にlatLngオブジェクトを与えることでその座標をgmap_v3.htmlの19/20行目のspan要素に流し込む関数で54行目で定義してます。

ちなみにdblclickイベントでは地図上でダブルクリックが生じたところにマーカーを移動させるというシステムの仕様のためにsetPositionメソッドを使ってマーカーの位置をイベント発生した場所に移動させてます。
これもまた引数はLatLngオブジェクトです。
マウスイベントオブジェクトのプロパティから取得しています。

なんとなく作ってみたものの感想としてはV2のがさくさく動いたって印象。
通信速度がある程度速いPCでだったらほとんどかわらず動くけどゴミスペックのPCだったら結構しんどいかもです。

誰かぼくにモンスターPCをかってください>m<

ps
今度ジオコードの使い方に関する記事もかきます~

No Comments
5月 23, 2010 in ajax, javascript

リアルタイム同期チャット

今回はリアルタイムな同期チャットを作ってみました。

考え方的にはぐーぐるさんが使ったことで有名なコメットとよく似ています。

ただPHPを使ってやりたかったのでcometは用いません。

そもそもコメットの特徴はクライアントサイドからサーバーへの要求の投げかけを一回にしてるところなのでその一回を半無限ループ使って常時接続状態にすればいいわけです。

以下がソースです。

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="content-script-type" content="text/javascript" />

<link rel="stylesheet" href="css/main.css" charset="utf-8" type="text/css" />
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript" src="js/chat.js"></script>
</head>

<body>
<div class="chat" id="chat"></div>
		<div class="commentarea" id="commentarea">
        	<textarea class="comment" id="comment"></textarea>
			<input type="button" class="submit" value="発言" onclick="remark();" />
        </div>

</div><!-- end Chat Program -->
</body>
</html>

chat.js

$(function(){
	$("#submit").click(remark);
	$.post("get_chat_log.php",{},get_message,"text");
});

function remark(){
	var txt = $("#comment").val();
	$.post("write_chat_log.php",{name:"oppai星人",message:txt});
	$("#comment").val("");
}

function get_message(text){

	var recs = eval(text);
	n = recs.length;

	for(var i = 0; i<n; i++){
		data = $("#chat").html();
		$("#chat").html(data +"<span class=\"name\">" +recs[i]["name"]+"</span> さんの発言:<br />"+"<span class=\"message\">"+recs[i]["message"]+"</span><br />\n");
	}
	$.post("get_chat_log.php",{},get_message,"text");
}

get_chat_log.php

<?php
set_time_limit(0);

$file_name = "log/chatlog.txt";

//ファイルの最終更新時間を取得
$o_time = filemtime($file_name);
$o_filesize = filesize($file_name);

while(TRUE){

	//キャッシュ削除
	clearstatcache();

	//今現在のファイルの最終更新時間を取得
	$n_time = filemtime($file_name);

	//アクセス時の最終更新時間と比較
	if($o_time!==$n_time){
		$n_filesize = filesize($file_name);
		$fp = fopen($file_name,"r+");
		$fp2 = fseek($fp,$o_filesize);

		//通常ファイルサイズ文読み込むがEOFになると終了する。
		$body = fread($fp,$n_filesize);
		fclose($fp);
		break;
	}
	//遅延
	sleep(1);
}

$new_line = explode("\n",$body);
$n = count($new_line);

$res = array();

for($i=0; $i<$n; $i++){
	$data = explode(">",$new_line[$i]);
	$account = $data[0];
	$message = trim($data[1]);

	$message = str_replace("&gt;",">",$message);
	$message = str_replace("&lt;","<",$message);

	$arr = array("name"=>$account,"message"=>$message);
	array_push($res,$arr);
}

$n = count($res);

$txt ="";
for($i=0; $i<$n-1; $i++){
	if($i==0 && ($n-1)!=1){
		$txt .= '\'[{"name":"'.$res[$i]["name"].'","message":"'.$res[$i]["message"].'"}';
	}elseif($i==0 && ($n-1)==1){
		$txt .= '[{"name":"'.$res[$i]["name"].'","message":"'.$res[$i]["message"].'"}]';
	}elseif($i==$n-2){
		$txt .= ',{"name":"'.$res[$i]["name"].'","message":"'.$res[$i]["message"].'"}]';
	}else{
		$txt .= ',{"name":"'.$res[$i]["name"].'","message":"'.$res[$i]["message"].'"}';
	}
}

echo $txt;
?>

write_chat_log.php

<?php
$name = $_POST["name"];

$msg = str_replace("\n","<br />",$_POST["message"]);
$msg = htmlspecialchars($msg,ENT_QUOTES);

$body = $name.">".$msg."\r\n";

$file_name = "log/chatlog.txt";

$fp = fopen($file_name,'a');
fwrite($fp,$body);
fclose($fp);
echo $body;
?>

以上の4ファイルです。

index.htmlのページ読み込みと同時にchat.js内でget_chat_log.phpへのajax通信が始まります。

set_time_limit関数の引数に0を代入することでphpの実行時間の制約を無限大に伸ばしてます。

そしてwhile(true)を用いて無限ループ。
sleepで引数時間に一回ずつループします。
ログファイルに更新があればbreakして差分をjsのコールバック関数にjsonフォーマットで受け渡し、js側で整形して出力します。
出力後、またget_chat_log.phpにアクセスして次の更新を待ち続けます。

次に発言時、index.htmlのonclickイベントでchat.jsのremark関数が動きwrite_chat_log.phpにajax通信し、入力情報をログに書き出しします。

これでリアルタイムなチャットが更新されます。
まぁ結構サーバーに負荷かかりますが。笑

2 Comments
5月 7, 2010 in PHP, ajax, javascript

Ajaxでデータベース更新

WEBサイトでDBを用いてシステム構築しているケースは多々あります。

使用するテーブルが1つならいいけど複数のテーブルを使用していて、更新の際にすべて変更しなきゃいけないときってめんどくさいですよね。

adminページ的なものを設けてもPHPで更新するとなるとページ遷移が必要になってTable1を更新→遷移→Table2を更新→遷移...みたいな。

というわけでこのページ遷移をなくす方法として非同期通信(Ajax)を使用する方法をあげときます。

一応例として作ったページはこちら

適当にフィールドにデータいれて修正ボタンを押してもらえたらDBの値が更新されます。
更新されたデータはテーブル情報のとこに出力されるようになってます。

まず用意するファイルは4つ

  • index.html
  • jquery.js
  • ajax_revise.js
  • revise.php

jquery.jsはJavaScriptのフレームワークです。 無料配布されてるのでこちらからダウンロードしてきて使用してください。

残りの三つは自分で勝手に作ってください。

ファイルの中身はこんな感じ

index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="ajax_revise.js"></script>
<link rel="stylesheet" href="main.css" type="text/css" />
<title>ajaxでデータベース更新</title>
</head>

<body>
<div id="tableinfo"></div>

<br />

<div>
    <h4>修正フォーム</h4>

    <table>
    <tr>
    <td>field1</td><td><input type="text" width="5" id="data1" /></td>
    </tr>
    <tr>
    <td>field2</td><td><input type="text" width="5" id="data2" /></td>
    </tr>
    </table>

    <br />

    <input type="button" value="修正" id="revise" />

</div>
</body>
</html>

ajax_revise.js

// JavaScript Document
$(function(){
	$.post("revise.php",{},function(res){
		$("#tableinfo").html("テーブル情報<br />field1:"+res.field1+"<br />field2:"+res.field2)
		$("#data1").val(res.field1);
		$("#data2").val(res.field2);
	},"json");
	$("#revise").click(revise);
});

function revise(){
	a = $("#data1").val();
	b = $("#data2").val();

	$.post("revise.php",{field1:a,field2:b},function(res){
		$("#tableinfo").html("テーブル情報<br />field1:"+res.field1+"<br />field2:"+res.field2)
		$("#date1").text(res.field1);
		$("#date2").text(res.field2);
	},"json");
}

revise.php

<?php
$hostname="******";
$username="******";
$password="******";

$dbname="******";

$conn = mysql_connect($hostname, $username, $password) or die(mysql_error());
mysql_select_db($dbname) or die(mysql_error());  

$sql = "SET NAMES utf8";
$res = mysql_query($sql) or die(mysql_error());

if(isset($_POST['field1']) && isset($_POST['field2'])){
	$field1=htmlspecialchars($_POST['field1'],ENT_QUOTES);
	$field2=htmlspecialchars($_POST['field2'],ENT_QUOTES);

	$sql = "update `test20091230` set
		`field1` = '".$field1."' ,
		`field2` = '".$field2."'
	where `no` = '1'";

	$res = mysql_query($sql) or die(mysql_error());
}

$sql = "select * from `test20091230` where `no`='1'";
$res = mysql_query($sql) or die(mysql_error());

$data = mysql_fetch_array($res, MYSQL_ASSOC);

$values = array('field1' => $data['field1'], 'field2' => $data['field2']);

$json = json_encode($values);

mysql_free_result($res);
mysql_close($conn);  

echo $json;

?>

index.html
5~6行目でjQueryとajax_revise.jsを読み込んでいます。

7行目はCSSなのであってもなくてもいいです。 
見栄えが少しマシになります。

12行目はajax_revise.jsからhtmlを流し込むためのDivです。(セレクタは#tableinfo)
21、24行目に修正データを入力するinputタグを配置しています。

30行目でボタンを設置し、このボタンのクリックと同時に修正されるようにします。

ajax_revise.js
2行目の$(function(){ はindex.htmlがすべて読み込まれたあとに実行されることを保証されてる範囲です。

3行目でrevise.phpにPOSTで通信してます。 返された値はjsonでresに格納されます。

4~6行目でresをindex.htmlの各セレクタに流し込みます。

8行目はイベントリスナの登録です。 11行目以降がボタンをクリックされたときの動きになるのですが、こちらは$(function(){の範囲外ですのでindex.htmlが読み込まれる前に実行される可能性があり、#reviseを正常に解釈できない可能性があるので先に登録しておきます。

11行目以降は前述の通り、修正ボタンをクリックされたあとの動きです。

12~13行目で修正フォームに記入された値をとりa,bに格納。
それを引数として15行目でrevise.phpにまた値を送っています。

以下は2行目~の部分と大差ないので省略します。

revise.php
2~6行目にそれぞれ自分のデータベースのデータを入力してください。

8~9行目はmysqlに2~6行目で定めたデータを使ってアクセス。

11~12行目はmysqlのエンコードの設定です。 僕のDBは少し変なことしてしまったのでこれが必要になります。 なくても動く人もいるけどあっても変なことにはならないので触らないのが吉

14~23行目はindex.htmlでボタンをクリックされ、ajax_revise.jsでデータをPOSTで送られてきたときに動くところで、受け取った値でデータベースを更新しています。 ちなみに今回はレコード番号1を更新するという形にしました。

26~27行目で更新後あるいはPOSTでデータが送られていなければそのままのレコードをとってきます。

29行目でレコードのデータを$dataに格納しています。(今回はレコードが1つしかないのが自明なのでそのままの代入でおkです)

31行目でそれを連想配列で保管しています。

33行目でjsonに変換しています。
もともとjsonに変換する関数はPECLにあったんですがPHP5.2以降では標準で存在します。
なので自分のPHPが5.2以降ならこのままでおkです。 以前ならPECLから引っ張てきてください。

35~36行目でmysqlとの通信終了

38行目で生成されたjsonデータを出力

ちゃっちぃプログラムですがこんな感じで非同期通信でのデータベースが可能になります。
ajax_revise.jsで普通にjQuery使っちゃってますが意味不明なかたは日本語リファレンスがあったと思うのでそちらを参照してください。

1 Comment
12月 30, 2009 in PHP, ajax, javascript