Google Chromeでは javascript の window.close() で自分自身を消すことができない?効かない?


表題の件、javascriptのwindow.close()について、いろいろとテストをしてみた。

結論から言うと、Google Chromeでは javascript の window.close() で自分自身を消すことができないです。効かないです、ハイ。

忙しい人や、とりあえず結果だけ知りたい人は別に以下読まなくてもいいんじゃね?以下は「できない」ことを検証しただけだから。

さてさて、
以下のような簡単なコードを書いてみてテストしてみる。

sample1.htm

<html lang="ja">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<script>
$(function(){
    $(document).on("click","#close_window",function(){
        //自分自身を閉じる
        window.close();
    });
});
</script>
<button id="close_window">Close Window</button>
</body>
</html>

↑のHTMLファイルを作りChromeブラウザの「お気に入り」から(URLアドレス欄にパスを張り付けてもおなじ)「sample1.htm」を表示させてボタン「Close Window」を押すと、

Scripts may close only the windows that were opened by it.

というエラーが出て画面を閉じることができない。
一方で、「sample1.htm」のファイルを「ファイルの右クリック→プログラムから開く→Google Chrome」とすると
あら不思議、さっきまでウンともスンとも言わなかったのに見事にタブが消えるじゃありませんか。

もうちょっとツッコんでテストしてみる。

以下の2つのファイルを作ってみる。

sample2.htm

<html lang="ja">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<script>
$(function(){
    var childWindow;
    $(document).on("click","#open_child_window",function(){
        //別窓でsample3.htmを開く
        childWindow = window.open("./sample3.htm","window_close_2","_blank");
    });
    $(document).on("click","#close_child_window",function(){
        //別窓で開いたsample3.htmを閉じる
        childWindow.close();
    });
});
</script>
<button id="open_child_window">Open Child Window</button>
<button id="close_child_window">Close Child Window</button>
</body>
</html>

sample3.htm

<html lang="ja">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<script>
$(function(){
    $(document).on("click","#im_close",function(){
        //自分自身を閉じる
        window.close();
    });
    $(document).on("click","#close_parent",function(){
        //自分自身開いた親を閉じる
        window.opener.close();
    });
});
</script>
<button id="im_close">Im Close</button>
<button id="close_parent">Close Parent Window</button>
</body>
</html>

例ごとく、Chromeの「お気に入り」から「sample2.htm」を開く。
ボタン「Open Child Window」を押すと普通に別窓で「sample3.htm」が開く。
別窓「sample3.htm」のボタン「Im Close」を押すと、別窓「sample3.htm」が普通に消えてくれる。
これは問題ないようだ。

もう一つのボタン「Close Parent Window」を押すと、これは効かない。
案の定、「Scripts may close only the windows that were opened by it.」だ。
さて、前の実験と同じく、「sample2.htm」を「ファイルの右クリック→プログラムから開く→Google Chrome」とすると
あら不思議、「Close Parent Window」も動作して「sample2.htm」が表示されているタブもスコッと消える。

最後にもう一つテスト。
以下の二つのファイルをつくる。

sample4.htm

<html lang="ja">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>
<body>
<script>
$(function(){
    $(document).on("click","#move_next",function(){
        //sample4.htmに画面移動する
        location.href="sample5.htm";
    });
});
</script>
<button id="move_next">Move Next</button>
</body>
</html>

sample5.htm

<html lang="ja">
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
$(function(){
    //即座に自分自身を閉じる
    window.close();
});
</script>
<span>ほげほげ!!</span>
</body>
</html>

これも同じように「お気に入り」からと「右クリック→プログラムから開く」で試してみると、
「お気に入り」のほうは「sample5.htm」が表示されたまま止まり、
「Scripts may close only the windows that were opened by it.」となるが、
「右クリック」のほうは「sample5.htm」が表示された瞬間に消える。

結論としては・・・・

  • Google Chromeでは親タブ、親ウィンドウをJavascriptから(window.close()で)閉じることはできない。
  • ただし、window.openで開いた子ウィンドであれば自分自身からでも親からでも閉じることができる。
  • もちろん子ウィンドウから親ウィンドウは消すことはできない。

WEBサイトやWEBサービスを作るうえで、
「ファイルの右クリック→プログラムから開く→Google Chrome」なんてやるわけないから、
実質のところGoogle Chromeでは親画面(=初期表示ウィンドウや初期表示タブ)はスクリプトから消すことはできないようだ。
まぁ考えてみればセキュリティ的にもUI的にもいきなり画面が消えるなんてことはNGだからっちゅうことかしらね。
ってことで、この記事を書くきっかけとなった「URL直打ちされてタブ画面として開かれてしまった画面を別ウィンドウに移動させる」という課題は頓挫いたしましたとさ、チャンチャン。

ちなみにIEでは自分自身をWindow.close()で消すことができます。ただ、「消していいですか?」的なダイアログがでるので、どっちみにユーザのクリック動作が必要になるけど。自動的にスコっとウィンドウやタブを落とすのはできないのね。

CSS3 Media Queries(メディアクエリ)書くときに必ず開くサイト


レスポンシブルサイトを作る時に必要なCSS3のMedia Queries(メディアクエリ)について、よそ様が沢山書いてくれているから細かくは書かないけど、Media Queriesを書くときに必ずみる(ってか詳細を忘れちゃってるのでこのサイト見ないとかけない)サイトがこのサイト。

デバイスに合わせてCSSを振り分ける「Media Queries」
http://dev.classmethod.jp/smartphone/device-media-queries/

とくにMedia Queriesが機能する条件を書くところが特に簡潔にまとめられていてよい。

引用

  • Max Width:
    • ビューエリアの最大幅。このサイズより小さい場合に適用
  • Min Width:
    • ビューエリアの最小幅。このサイズより大きい場合に適用
  • Max Device Width:
    • デバイスサイズの最大幅。このサイズより小さい場合に適用
  • Min Device Width:
    • デバイスサイズの最小幅。このサイズより大きい場合に適用
  • Device Pixel Ratio:
    • デバイスの解像度(webkit)
  • Orientation:
    • デバイスの向き

GoogleMapで地図描画前に描画要素をdisplay:none;すると表示がおかしくなる(中心がズレて表示される)


GoogleMapAPI とか GoogleMap埋め込み などを利用している場合、MAP描画前にiFrame要素や、APIで描画仕様としているボックス要素を display: none; で表示を消してしまうと表示がおかしくなる。

べつに表示されないわけではないのだけど、地図の中心がずれたりする。この問題の回避策はJavascriptなどを利用してロード開始時には表示しておき、ロード後に非表示にするしかない。

試してみたところ、

<div style="height: 0px; overflow: hidden;">

としても地図は問題なく表示されたので、初期設定は左記ほのとおりスタイルを設定しておき、ロード後にjQueryなどで

$("div").css("height","").css("overflow","")

として初期設定を消してやればいいだろう。

[HTML&CSS]Google Chrome for Androidでは、BOX要素のmax-heightを%で指定するとoverflow設定が効かない


Google Chrome for Androidでは、DIV要素などのBOX要素のmax-heightを%で指定するとoverflow設定が効かない。

ちなみに、Android標準ブラウザとiOSのMobile Safariではmax-heightを%で指定しても問題なくoverflow設定が効く。Chrome for Androidだけ困ったちゃんなんです。コマったね。

まぁ回避策はいろいろあるんだろうけど、俺は安易に、jQueryで

$(“div.****”).css(“max-height”,$(window).height()*0.95)

ってやっちゃった。

[HTML&CSS] Google Chrome for Android でCSSのwidth指定がおかしな挙動をする。親DIV要素のwidth値を正しく取得できない。


Android版chromeのバグか?

以下のようにHTML要素を組む。

これをAndroid chromeで表示させるとこうなる。

現象を整理すると以下の通り。

  • つねに子DIV要素1は正しく表示される。
  • margin、padding類は全て0pxを指定している。
  • Android chrome 以外のPCとスマフォで使用できる思いつく限りの全てのブラウザでこの現象は発現しない。
  • 当該ブラウザで必ずこの問題が再現されるわけではなく「たまに」正しく表示されることがある。
  • 「display:none;」でいったん非表示にしてから「display:block;」で再表示すると問題が解消される。

回避策はすでに示した通り、displayスタイルで再表示してやるか、もしくは初めから「display:none;」としておき、windowロードが完了した後にjQueryか何かで「display:block;」としてやれば、問題は回避される。

問題の原因は不明で、HTML、CSSレベルではどうやっても解決できなかった。

最低構成にしても起こる時は起るし、どんなに複雑に構成していても起こらないときは一切起こらない。

う~ん、でも他のサイトにコレらしきバグ報告がないってことは俺が悪いのか???

[HTML&CSS] ブロック要素に対して、floatとdisplay:table-cell;→vertical-alignは同時に設定することはできない


いまさらだけど、ブロック要素(div要素など)にfloatを設定してレイアウトした場合、display:table-cell;をつかってvertical-alignを設定することはできない。しってた?何を当たり前のこと言ってんだ、って?ああ、そうさっ!!ついさっき知ったよっ!!コンチクショウッ!!

ということで、display:table-cell;をつかってvertical-alignを設定する際には、レイアウトはdisplay:table-row;やdisplay:table-cell;を使ってレイアウトするか、ボックス要素を入れ子状態にして、子ブロックをdisplay:table-cell;→vertical-alignとすれば問題ない。

もちろんだけど、display:table-cell;をつかってvertical-alignを設定するテクニックはIE6,IE7では使えない。あーIE6,IE7,IE8とか早く死んでくんねーかなー。大事な事なので2度いいます。あーIE6,IE7,IE8とか早く死んでくんねーかなー。

[HTML] CSSレイアウトをしていてfloat指定すると外側のブロック要素からハミ出る現象をoverflowで回避する


CSSでレイアウトする事が全盛な昨今、

要素を「float: left;」と指定してレイアウトを組む事が多々ある。

一方でfloat指定すると外側のdivタグ等のブロック要素からハミ出る問題が発生する。

この問題の回避方法を一言でいえば、

外側ブロック要素に“overflow: auto;”と指定する

と回避できる。

簡単なことなんだけど、結構気がつかない。

備忘録を兼ねて。