外部ファイルをjsで読み込む時に気をつけたい基本事項

       
同期・非同期?外部ファイルをjsで読み込む時に気をつけたい基本事項

CMS(WordPressなど)を使わずに静的なコーディングをする際、もうほぼ必須と思われる共通部分のJS読込。
それから絶対パスが使えないとか、なんか「難しそうに見える」同期・非同期という言葉で挫折した方、Welcome to Wenblish!




同期・非同期って何?

ご存じの方は飛ばしてください。
図で書くとこんな感じです。
同期処理と非同期処理
同期処理は、命令1の完了を待ってから2の命令が実行されますが、非同期処理では1の完了を待たずに2の命令が実行されるという具合です。
全部が漢字なので、何となく難しそうなイメージが醸し出されているのですが、特段難しい話ではないと思いますです。

外部ファイルを非同期で読み込む基本

色々方法はあるのですが、
対象となるファイルのパスは、命令を書く場所から見た相対パスか、絶対パスで書きます。

jQueryの場合

1. loadで読み込む

<br />
$(function() {<br />
   $("#footer").load("../common/html/footer.html");<br />
});<br />

 
2. getで読み込む

<br />
$(function() {<br />
   $.get("../common/html/footer.html", function(data){<br />
      $("#footer").text(data);<br />
   });<br />
});<br />

 
3. ajaxで読み込む

<br />
$(function() {<br />
   $.ajax({<br />
      url:'../common/html/footer.html',<br />
      success: function(data){<br />
         $("#footer").text(data);<br />
      }<br />
   });<br />
});<br />

IE向けのajax場合

IE6でも動くっぽいもの(すみません、確認はしてません)。

<br />
function createXMLHttpRequest() {<br />
   if (window.ActiveXObject){<br />
      try {<br />
         return new ActiveXObject("Msxml2.XMLHTTP");<br />
      }<br />
      catch (e) {<br />
         try {<br />
            return new ActiveXObject("Microsoft.XMLHTTP");<br />
         }<br />
         catch (e2) {<br />
            return null;<br />
         }<br />
      }<br />
   } else if(window.XMLHttpRequest) {<br />
      return new XMLHttpRequest();<br />
   } else {<br />
      return null;<br />
   }<br />
}<br />
// </p>
<p>      var httpObj = createXMLHttpRequest();<br />
      var data = "";<br />
      httpObj.open("GET", "../common/html/footer.html", true);<br />
      httpObj.onreadystatechange = function() {</p>
<p>      if (httpObj.readyState == 4) {<br />
         data = httpObj.responseText;<br />
         var node = document.getElementById("footer");<br />
         node.innerHTML = data;<br />
      }<br />

例えば、普通にグローバルナビゲーション・サイドナビゲーション・フッターの3つの外部ファイルを呼び出す時などは、完了を待つ必要はありませんよね??
ですので、ここでは非同期で呼び出します。3つの呼び出し命令を書いて、どんどん読み込んじゃう。完了を待っていたら読込が遅くなってしまいます。

順番が必要な場合は同期処理をする

例えば、あるファイルを読み込んで、その中身をゴニョゴニョしてから処理2に渡す、などの場合です。

jQueryの場合

例えば、getの場合ですと・・・

<br />
$.get('file1', function(hoge) {<br />
   $.get('file2', function(hige) {<br />
      // file1, file2の両方を使った処理<br />
      $.get('file3', function(homu) {<br />
         // file1, file2, file3 を全部使った処理<br />
      });<br />
   });<br />
});<br />

ネストふかーい。jQueryのバージョン1.5から使えるようになったDeferredをご紹介します。

<br />
$.when($.get('file1'), $.get('file2'), $.get('file3'))<br />
   .done(function(file1, file2, file3) {<br />
      // file1, file2, file3 全部を使った処理<br />
   });<br />

ネストの問題だけでは無いらしいので、下記のページも是非ご覧下さい。
結局jQuery.Deferredの何が嬉しいのか分からない、という人向けの小話

ActiveXObjectの場合

おまけ程度です。

<br />
function createXMLHttpRequest() {<br />
   if (window.ActiveXObject){<br />
      try {<br />
         return new ActiveXObject("Msxml2.XMLHTTP");<br />
      }<br />
      catch (e) {<br />
         try {<br />
            return new ActiveXObject("Microsoft.XMLHTTP");<br />
         }<br />
         catch (e2) {<br />
            return null;<br />
         }<br />
      }<br />
   } else if(window.XMLHttpRequest) {<br />
      return new XMLHttpRequest();<br />
   } else {<br />
      return null;<br />
   }<br />
}<br />
//<br />
      var httpObj = createXMLHttpRequest();<br />
      var data1, data2, data3;</p>
<p>      httpObj.open("GET", 'file1', false);<br />
      httpObj.overrideMimeType('text/xml;charset=Shift-JIS');<br />
      httpObj.send(null);<br />
      data1 = httpObj.responseText;</p>
<p>      httpObj.open("GET", 'file2', false);<br />
      httpObj.overrideMimeType('text/xml;charset=Shift-JIS');<br />
      httpObj.send(null);<br />
      data2 = httpObj.responseText;</p>
<p>      httpObj.open("GET", 'file3', false);<br />
      httpObj.overrideMimeType('text/xml;charset=Shift-JIS');<br />
      httpObj.send(null);<br />
      data3 = httpObj.responseText;</p>
<p>      // file1, file2, file3 を使った処理</p>
<p>

ローカル環境で動かしたい、どうしても!って場合

例えばクライアントさんにファイルを送って見てもらうなどの場合(サーバに上げないでやり取りする場合)、
絶対パスが使えない=ナビゲーションリンクをどうしたらいいのでしょう?
要するに、階層が違うページに読み込んだ時、ローカル環境で絶対パスだとリンクが切れちゃう(画像もダメ)という件です。
クライアントさんにバーチャルサーバを入れてもらうとか、無理っすよね・・・。
 
というわけで、関数に階層を現す引数を用意して、それによって「../」をその階層の分だけURLの部分に足してあげればよいのです!

<br />
function(階層数) {<br />
   // ここで「../」を階層数の分だけ足してあげる<br />
}<br />

ソースコードは敢えて公開しませんが、もうおわかりですよねっ!

Chromeでローカルのjsが動かないんですけど・・・

そうなんです、セキュリティの関係なのか、Chromeではデフォルトでは動きません。
実行パラメータに
–allow-file-access-from-files
をつけて起動することで可能になるのですが・・・それもクライアントさんには強要できませんよね・・・。
 
仕方ないので、クライアントさんにはChrome以外でお願いしましょう。
WindowsならIE、MacならSafariで試してもらえると思います。


同期処理・非同期処理・ローカルでの動かし方などについて書きましたが、いかがでしたでしょうか。
間違えがあったらごめんなさい。



英作文のフルーツフルイングリッシュ