JavaScript + Ajaxの最近のブログ記事

<IFRAME src="no.html" width="500" height="150" frameborder="0" id="ifr"></IFRAME>
というIFRAMEタグがあったとしましょう。
IFRAME内のURLを変更する場合、IEなら

ifr.location.href = "移動したいページ";

で良いのですが、Firefoxはうまくいきません。
Firefoxなら

document.getElementById("ifr").src = "移動したいページ";

と指定します。
下の方法はIEでも使えるのでこちらで統一すると良いかもしれません。

Google Maps では画面遷移のないシームレスな画像読み込みが行われます。
それにはAjaxと言われる最新技術が使われています。

Ajaxを使わないとシームレスな通信が不可能かと言われるとそうではありません。
今まではフレームを使ってシームレスな通信を行っていました。
実際に体験してもらった方が早いと思いますので以下のページをご覧ください。
Yahoo!検索 画面遷移無し(非同期通信) - フレームバージョン

このフレーム通信には、test2_1.html(親フレーム)、test2_1_sub.html(下フレーム)、test2_1_dummy.html(上フレーム(通信受信用、見えないフレーム))、test2_1.php(Web通信用)が使われています。
test2_1.html

<HTML><HEAD>

<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS">

<TITLE>Yahoo!検索 画面遷移無し(非同期通信) - フレームバージョン</TITLE>

</HEAD>

<FRAMESET rows="0,*" frameborder="0" border="0" framespacing="0">

<FRAME src="test2_1_dummy.html" scrolling="NO" noresize marginwidth="0" marginheight="0" frameborder="0" name="up">

<FRAME src="test2_1_sub.html" frameborder="0" name="main">

<NOFRAMES>

<BODY>フレームが使用できないブラウザでは実行できません</BODY>

</NOFRAMES>

</FRAMESET>

</HTML>

rows="0,*"として見えないフレームを作る必要があります。
test2_1_sub.html
<HTML>

<BODY>

<SCRIPT language="JavaScript">

<!--

function get_data(){

  parent.up.location.href = "test2_1.php?key="+document.fo.yahoo.value;

}



function set_data(html){

  document.all("html_div").innerHTML = html;

}

//-->

</SCRIPT>

<FORM name="fo">Yahoo!検索<BR><INPUT size="20" type="text" name="yahoo"><INPUT type="button" value="検索" onclick="get_data();"></FORM>

<HR>

<DIV id="html_div"></DIV>

</BODY>

</HTML>

ここでget_data()は通信開始関数、set_data()は通信受信関数です。
parent.up.location.href =とすることで、見えない「上フレーム」を指定ページに移動させています。(ここでは検索用phpを起動します。)

Yahooの通信はWebページを簡単に取得できるPHPが使われています。
test2_1.php

<?php

$key = $_GET['key'];

$get_html_dat = file("http://search.yahoo.co.jp/search?p=$key");

$all_html_dat = "";

for($i=0;$i<count($get_html_dat);$i++){

  if(!eregi("<li><div>",$get_html_dat[$i])){continue;}

  $get_html_dat[$i] = ereg_replace('"', "", $get_html_dat[$i]);

  $all_html_dat .= rtrim($get_html_dat[$i]);

}



echo "<HTML><BODY><SCRIPT>parent.main.set_data(\"$all_html_dat\");</SCRIPT></BODY></HTML>";



?>


PHPは、$get_html_dat = file(・・・);のたった一行で$get_html_datに配列としてWebページを取得できます。($get_html_dat[0]は一行目、$get_html_dat[1]には二行目・・と格納されています。)
また、結果を表示する際に、取得したデータをそのまま表示するのではなく、<li><div>がある行のみを表示し、存在しない行は飛ばします。
ereg_replace('"', "", $get_html_dat[$i]);では、JavaScriptエラーの原因となるダブルクォーテーション(")を変換しています。
最後にparent.main.set_data(\"$all_html_dat\");で、test2_1_sub.htmlのset_data()関数を引数(検索結果データ)込みで実行します。
そうすると画面に表示されるというわけです。

ちなみにtest2_1_dummy.htmlは何も書く必要はありません。(ダミーファイルです。)

さて、このようにフレームを用いた場合、ほとんどのブラウザで動作するという利点(携帯のフルブラウザでも可能です。たとえばこちら)がありますがデメリットとして、多くのファイルを用意する必要があり、煩わしいものとなっています。

そこでAjaxを使ってみましょう。サンプルを見てみるとわかりますが、動作はフレーム版とほぼ同じです。
Yahoo!検索 画面遷移無し(非同期通信) - Ajaxバージョン

この方法だと、test2_2.html(メインファイル、通信受信兼)、test2_2.php(Web通信用)と、とても少ないファイルで通信できます。
ちなみにAjax共通関数に関してはこちらを参照しました。

さて、内容を見ていきましょう。
test2_2.html

<HTML>

<BODY>

<SCRIPT language="JavaScript">

<!--

function get_data(){

  httpObj = createXMLHttpRequest(set_data);

  if(httpObj){

    httpObj.open("GET","test2_2.php?key="+document.fo.yahoo.value,true);

    httpObj.send(null);

  }

}



function set_data(){

  if((httpObj.readyState == 4) && (httpObj.status == 200)){

    html = httpObj.responseText;

    document.all("html_div").innerHTML = html;

  }

}



// HTTP通信用、共通関数

function createXMLHttpRequest(cbFunc){

  var XMLhttpObject = null;

  try{

    XMLhttpObject = new XMLHttpRequest();

  }catch(e){

    try{

      XMLhttpObject = new ActiveXObject("Msxml2.XMLHTTP");

    }catch(e){

      try{

        XMLhttpObject = new ActiveXObject("Microsoft.XMLHTTP");

      }catch(e){

        return null;

      }

    }

  }

  if (XMLhttpObject) XMLhttpObject.onreadystatechange = cbFunc;

  return XMLhttpObject;

}

//-->

</SCRIPT>

<FORM name="fo">Yahoo!検索<BR><INPUT size="20" type="text" name="yahoo"><INPUT type="button" value="検索" onclick="get_data();"></FORM>

<HR>

<DIV id="html_div"></DIV>

</BODY>

</HTML>

createXMLHttpRequest(・・・);のカッコ内に受信後に実行される関数名を記述します。ここではset_dataを実行するようにしています。
httpObj.responseTextには受信データが入っています。後はtest2_1_sub.htmlとあまり変わりません。

test2_2.php

<?php

$key = $_GET['key'];

$get_html_dat = file("http://search.yahoo.co.jp/search?p=$key");

$all_html_dat = "";

for($i=0;$i<count($get_html_dat);$i++){

  if(!eregi("<li><div>",$get_html_dat[$i])){continue;}

  $get_html_dat[$i] = mb_convert_encoding($get_html_dat[$i],"UTF-8","auto");

  $all_html_dat .= $get_html_dat[$i];

}

echo $all_html_dat;

?>

mb_convert_encoding($get_html_dat[$i],"UTF-8","auto");
で、文字コードをUTF-8に変換します。そうしないと文字化けします。
今回はダブルクォーテーションを変換したり、最後の出力を<SCRIPT></SCRIPT>で囲む必要はありません。

このように二通り試しましたが、あなたならどちらを使いますか?

まず知っておかなければならないことが、
経度、緯度の表し方がいろいろとあるということです。

まず大きな違いが、日本測地系と世界測地系です。
同じ地点でも、この違いにより世界測地系の方が
南東におよそ450mずれた地点を表すことになります。

【参考】東京都庁の経度、緯度
日本測地系・・経度:139.69487、緯度:35.68627
世界測地系・・経度:139.69167、緯度:35.68949

それでは、それぞれの値を変換するにはどうすればいいでしょうか。
次のような式があります。変数の定義は次の通りです。
(ln:入力経度、la:入力緯度、lng:変換後経度、lat:変換後緯度)

日本→世界

lng = ln - la * 0.000046038 - ln * 0.000083043 + 0.010040;

lat = la - la * 0.00010695 + ln * 0.000017464 + 0.0046017;

世界→日本
lng = ln + la * 0.000046047 + ln * 0.000083049 - 0.010041;

lat = la + la * 0.00010696 - ln * 0.000017467 - 0.0046020;


次の違いが度表示、度分秒表示などによる違いです。
(時間の計算で「12分15秒→12.25分」などと同じような変換です)

【参考】東京都庁の経度、緯度
日本測地系(度)・・経度:139.69487、緯度:35.68627
日本測地系(度分秒)・・経度:139.41.41.53、緯度:35.41.10.57

JavaScriptでの変換プログラム例です。
Perl、PHPで使用したい場合は適宜変更してください。

度→度分秒(ddd.mm.ss.ss)
(innum:入力数値(ddd.ddd形式)、outnum:変換後数値)

EH = parseInt(innum);

EM = parseInt((innum-EH)*60);

ES = (innum-EH-(EM/60))*3600;

ESS = (Math.round(ES*10)/10);

if(EM<10){EM = "0"+EM;}

if(ESS<10){ESS = "0"+ESS;}

if((ESS+"").indexOf(".") == -1){ESS = ESS+".0";}

outnum = EH+'.'+EM+'.'+ESS;

度分秒(ddd.mm.ss.ss)→度
(innum:入力数値(ddd.nn.ss.ss形式)、outnum:変換後数値)

tmp_in = innum.split(".");

outnum = parseInt(tmp_in[0])+(((tmp_in[1]*60+parseInt(tmp_in[2])+tmp_in[3]/10)*1000)/3600000);

困ったことに現在の対応状況は
・Google Maps API 【世界測地系】 【度表示】
・mapionなど国内主要地図サイト 【日本測地系】 【度分秒表示】
・AUGPSケータイ 【どちらも可(datum、unit変数で指定)】
と、バラバラですので変換して統一する必要があります。

ということで、当サイトは、Google Maps API などで表示するデータも
すべて日本測地系、度分秒表示に変換して表示しています。

このアーカイブについて

このページには、過去に書かれたブログ記事のうちJavaScript + Ajaxカテゴリに属しているものが含まれています。

前のカテゴリはGoogle Maps APIです。

次のカテゴリはPHPです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。