window.openの振る舞い

Webサイトを作成していると自分が紹介したいお店の情報や記事についてリンクを設定し、ページ遷移させることが多々ある。

 

リンク遷移の代表的な方法として以下がよく用いられる。

1:onclick(ontouch)系イベントを用いたwindow.openによる、リンク遷移

2:onclick(ontouch)イベントを用いたlocation.hrefによる、リンク遷移

3:aタグを用いたリンク遷移

 

android端末で1の方法を試したところ、別ウィンドウが立ち上がらず、

タッチしても反応しない現象が発生した。

 

ググってみたところ、以下ページが参考になった。

参考:http://cygx.mydns.jp/blog/?arti=475

 

OS側で検知した動作が、ブラウザ(WebKit)側でUserGestureかどうかを判別する処理が行われているらしく、ブラウザの判別によってスクリプトの挙動が変わるぽいです。

 

なので、反応しなかった理由としては、端末をタッチした動作が、androidのデフォルトブラウザでUserGestureと認識されず、リンクが開かれなかった。

 

そもそもブラウザ側でなぜそのような判別ロジックが入っているのかというと、

先ほどのページにも記載されていますが、セキュリティ的な観点で機能が搭載されているみたいです。

 

UserGestureを判別しないと、

例えば、最近よく見かける広告をタッチすると動画再生が始まる広告などが、

サイトを表示のタイミングで勝手に再生されることも可能になる。

 

最近は、通信料定額で契約を結んでいる人が多いと思うが、従量課金で契約を結んでいる人からすると勝手に動画がダウンロードされて再生されたらたまったものではない。

 

このようなことを抑制するために入っているぽいです。(iPhoneも同様?)

 

話がそれましたが、画面をタッチしたのに、なぜUserGestureとして認識されなかったのか?というとよく調べていないので分かりませんが、多分バグだと思われます。

(android4系だとちゃんと動きました)

 

で、スクリプト側で対応する方法としては、以下が参考になりました。

http://stackoverflow.com/questions/3601184/window-open-returns-undefined-when-called-from-settimeout-on-android

 

上記を参考にhtmlを書いてみました。

 

<!DOCUTYPE html>

<html>

<head>

<script type="text/javascript">

var open = function() {

window.open('http://www.yahoo.co.jp');

};

var link = function() {

var buttonnode= document.createElement('input');

buttonnode.setAttribute('type','button');

buttonnode.setAttribute('style','display:none;');

document.body.appendChild(buttonnode);

buttonnode.onclick = open;

window.setTimeout(function() { buttonnode.click()},100);

};

</script>

</head>

<body>

<div onclick="link()">遷移しますよ</div>

</body>

</html> 

 

これでandroid2系でも無事別ウィンドウで遷移するようになりました。