2012-10-22 33 views
11

私はGoogleマップAPIのJavaScriptを非同期にしようとしています。非同期読み込みjavascript with document.write

ので、通常のスクリプトタグは<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>

に動作します。しかし、以下の非同期バージョンにはありません。

(function() { 
    var gmap = document.createElement('script'); gmap.type = 'text/javascript'; gmap.async = true; 
    gmap.src = 'https://maps.googleapis.com/maps/api/js?sensor=false'; 
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gmap, s); 
})(); 

いくつかのブレークポイント+検査アクションの後、この行が非同期モードで正しく動作しないことがわかりました。

document.write('<' + 'script src="' + src + '"' + 
' type="text/javascript"><' + '/script>'); 

同期モードでのドキュメントオブジェクトは、「HTMLDocumentの」ですが、非同期モードでは代わりに「#document」です。ページが読み込まれた後、ドキュメントオブジェクトに何かが発生しました。思考?

乾杯。

更新:この質問はGoogle Maps APIを非同期ロードするのではなく、document.writeが起動されない理由です。この行にブレークポイントを設定すると、document.write関数が存在することがわかります。これはdocument.writeがネイティブであるという事実と関係がありますか?

答えて

7

document.writeは、非同期スクリプトから呼び出すことはできません。これは、ドキュメントから切り離されているため、JSパーサーはどこに配置するのかわからないためです。最高でも、ブラウザはそれを無視します。最悪の場合、(ドキュメントのロードが完了した後にdocument.writeを呼び出す場合のように)現在のドキュメントの上に上書きすることができます。

残念ながら唯一の答えは、Google APIの場合はおそらく実行可能なオプションではないスクリプトを書き直すことです。

+0

ありがとうございました。私はこの行でブレークポイントを行い、自分自身をdocument.writeしようとしました。それはwrite()関数を見つけたので、それは奇妙です。書き込み関数が切り離されている場合、なぜそれは未定義ではないのですか? – user1736525

+0

yea googleは冗談です – neaumusic

2

スクリプトURL内でパラメータcallbackを使用すると、スクリプトでwrite()が使用されず、APIを非同期に読み込むことができます。

参照:https://developers.google.com/maps/documentation/javascript/tutorial?hl=en#asynch

+0

ええ、私はコールバックを持っていましたが、jquery mobileの別の問題に遭遇しました。そこにはGoogleマップのapiが複数回ロードされています。私は警告メッセージが気に入らなかった。 – user1736525

+2

警告が気に入らない場合は、APIを複数回読み込まないでください。 –

+0

jqm ajaxモードを使用しているasp mvcのjquery mobileです。したがって、jqmイベントを使用するのではなく、APIを一度読み込む方がきれいに見えます。 – user1736525

1

は、市場や博士モールでは説明の理由から、document.write()を使用しないでください。代わりにGoogle's example of async loadingのようにappendChild()を使用してください。

4

アマゾン広告を非同期に読み込むと、非常によく似た問題が発生しました。

document.write = function(content) { 
    if (document.currentScript) { 
    var src = document.currentScript.src 
     .replace(/\#.*$/, '') 
     .replace(/\?.*$/, '') 
     .replace(/^.*\/\//, ''); 
    setTimeout(function() { 
     var script = $('script').filter(function() { 
     var scriptSrc = $(this).attr('src'); 
     return scriptSrc && scriptSrc.indexOf(src) !== -1; 
     }); 
     $('<div></div>') 
      .addClass('doc-write') 
      .html(content) 
      .insertAfter(script); 
    }, 0); 
    } else { 
    HTMLDocument.prototype.write.apply(document, arguments); 
    } 
}; 

このアプローチは、上の改善することができるが、それは私のニーズに十分に動作します:私はその行動変更することにより、このような状況のために私のアプリで近似document.writeを得ることができた(この場合は$をjQueryのを指します)。うまくいけば、あなたはそれが役に立つと思うでしょう。

+0

ちょうどこれを投票しましたが、今IE 11でサポートされていないことを認識しました。 – downatone

+0

最初のAPIロードで 'callback = somefunction'パラメータを使用します – neaumusic

0

私はこの問題でかなり苦労して以来、ここにコメントを追加しています。スクリプトを非同期にロードする場合(たとえばボタンをクリックして)、のように、siteに従ってください。

私が最初にコールバック値を与えなかったときにエラーdocument.writeを取得しました。そして、コールバックを与えた後、window.initializeエラーが発生しました。なぜなら、私のコードには初期化関数がないからです。私はそれを私の関数名(loadMapのようなもの)に変更し、それが動作するようになった。

正直言って、サイトからコードをコピーすればうまくいくはずです。 window.onloadは、上記の機能をトリガーするために必要なものに交換してください。

関連する問題