2012年8月29日水曜日

BODYタグのONLOADが動かなくてハマる。Twitterのツイートボタンが原因か?

今日、サイトに埋め込んでいるGoogle Mapsが表示されなくなっているのに気づいた。
Internet Explorer8や9で表示されない。Google chromeやFirefoxでは表示される。

Google MapsのAPIはBODYタグのONLOADから呼び出されるコードで初期化している。
初期化コードの前にalert()を入れてみるが表示されない。
どうやら、BODYタグのONLOADが呼ばれていないらしい。そのためGoogleマップの初期化がされず、表示されないようだ。

BODYタグのONLOADが実行されない原因を調べるため、HTML中のいろんな部分のコードを削って、少しずつ追求していく。
そうすると、Googleの+1ボタンとTwitterのツイートボタン、それからResearch Artisanの3つのコードが関連しているらしいところまで分かった。
3つのコードのうち、ひとつを削ると、BODYタグのONLOADが呼ばれたり、そうかと思えばときどき呼ばれなかったりと、不安定な動きをする。なにかのタイミングによって動作が変わる。

BODYタグのONLOADはJAVAスクリプトで上書きすると、それまで設定されていたイベントリスナーが上書きされてしまう仕様らしい。
<BODY ONLOAD="init()">
と書いているのだが、これが3つのコードうち、どれかによって上書きされて、実行されないのではないかと考えた。上書きされるタイミングがそのときのスクリプトのダウンロード時間の長短によって変わり不規則な動きになっているのではないかと推測した。

まず、Googleの+1ボタンを、SetTimeout関数で遅延実行させてみた。Googleの+1ボタンのスクリプトがBODYタグのONLOADを上書きしていると仮定すると、その実行タイミングを遅らせることで、上書きを回避する作成だ。
しかし、結果は変わらない。
次にTwitterのツイートボタンのコードを遅延させてみたところ、今度はONLOADが呼ばれる。

以上のことから、TwitterのツイートボタンのスクリプトにBODYタグのONLOADを上書きするコードが含まれていて、その実行タイミングによって、挙動が不安定になることがあると結論付けることにした。

具体的には、以下のコードの赤字部分を追加して、実行タイミングを遅らせることで解決した。
<a href="https://twitter.com/share" class="twitter-share-button" data-lang="ja"></a>
<script>
setTimeout(function(){
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
}, 1000);
</script>

あまりスマートな方法ではないかもしれないが、ひとまずは回避できた。

0 件のコメント: