フレームページをHTML5化する方法


普段、残業なんて滅多にしない職場で働いている自分ですが、この2週間ほどは激務でした(どれぐらい激務だったかはいいません。あくまで個人的にそう思っただけで、中にはそんなの激務じゃないと言われそうなレベルの量なので)

それはともかく、その間にやっていた仕事がframesetやframeタグを使っているフレームを利用したHTMLファイルをHTML5化するというもの。しかし、知ってる人も多いと思いますが、framesetやframeタグはHTML5で廃止されてしまっています。とりあえず代替方法としてiframeタグを使うことになったのだけれども(この実装方法に突っ込まないでください。時間がなかったのでこうするしかなかった)、最初、うまい実装方法が思いつきませんでした。しかも、対応ブラウザはIE6以上と言われています(HTML5なのに、IE6以上って………)。

例えば、以下のようなコード。

サンプルページ
ヘッダとして上部に50px、フッタとして下部に70px、そしてメインのページをその間に入れたフレームページです。ヘッダとフッタは問題ありません。問題はメインページです。動的に高さを変更しなければいけないわけですが、うまい方法が思いつきませんでした。

最初はそれぞれのiframeをtable,tr,tdタグで囲って、tableの高さを100%にし、一番上のtrの高さを50px、一番下のtrの高さを70pxにしてみました。一見、うまくいったように思えたのですが、IE10以下でダメでした・・・。

次に考えたほうほうが、#mainをdivタグで囲み、そのdiv(#main_containerとする)をbodyと同じ幅と高さと位置にして、box-sizingをborder-boxにしたうえで、padding-topを50px、padding-bottomを70pxにしたうえで、#mainの高さと横幅を100%にしたらいけるんじゃ・・・なんて思ったけど、よくよく考えるとIE7ではbox-sizing非対応だったのでできません(IE6はもともとbox-sizing:border:box;と指定した時と同じ振る舞いだったはずです)。

困ったなぁ。どうしたらいいんだ・・・。と思いながらふと思いついた。先ほどの#main_containerのtopを50pxにして、bottomを70pxにしたらどうなるんだろう・・・。と。

結果、期待通り、上部に50px、下部に70px空いた要素となりました(てっきり、どっちも指定している場合、どっちかが優先されるもんだと・・・。CSSはある程度わかってきたと思ったんだけどなぁ。CSS界隈では常識だったりするんだろうか?)

というわけで、以下が実装結果。

CSS

HTML

サンプルページ

IE6やIE7ではうまくいかないところもあったので、何度か試行錯誤してどのブラウザでも実装することができました。同じように左・中央・右にわけたフレームページでは下記のようになります。

HTML4

HTML4:サンプルページ

HTML5

HTML5:サンプルページ

応用として、framesetの中にframesetがあるページも下記の通り。
HTML4:サンプルページ
HTML5:サンプルページ

ただし、最後のはIE6でうまく動きませんでした。こういうページの場合は、最初に作ったframe1-html5.htmlの中の#mainのsrc属性を、二つ目に作ったframe2-html5.htmlにするほうがいいかもしれません。

HTML5の仕様から削除されたhgroupについて調べてみた


確か、昨年(2013年)の春頃にHTML5の仕様から削除されたhgroupタグ(参考:HTML5 勧告候補に main 要素が追加、hgroup 要素は予定通り削除 | WWW WATCH)。にも関わらず、今年に発売されたHTML5について描かれてる本にhgroupタグについての記述が書かれているのを何冊か見てきました。
具体的にいうと、下記の3冊に、hgroupタグについての記述が書かれていました。

この中だと、『フロントエンド開発徹底攻略』が過去にWeb+DBで掲載された特集を収録した本で、『モダンWeb』は2013年4月に発売された本の翻訳本なので、分からなくはないのですが、最初の本はそういった理由があるわけではなさそうです(大学の教科書用として作られたそうなので、もっとチェックしてほしかったところ)。

自分はhgroupを知ったのはいつだったかは覚えてないのですが、このタグを知った時にモヤモヤしたような気がします。例えば、下記のようなHTMLの構文があったとします。

これにhgroupを入れると下記のようになります。

こんな書き方需要ないだろと。

いやまあ、こんな書き方する人いるわけないだろ! と突っ込まれそうなので、実際にどう使われていたかというと、ウェブサイトの主題と副題(セクションの見出し)をグループ化する時に使われていたようです。例えば、ここのブログだと、下記のようになります。

って、いま気づいたけど、このブログ、ブログタイトル箇所はhgroupで囲ってあったのか・・・。いい加減、変更しなければ・・・。

さて、そんなhgroupタグですが、よくよく調べてみると、実際にはW3Cの仕様からは削除されたけれども、WHATWGの仕様からは削除されてないようです(参考:W3C HTML5仕様から削除されたhgroup要素のメモ – 血統の森+はてな)。このへんはよく分からないのですが、また仕様に追加されるということもあるということなのだろうか。ややこしいので、削除したり復活したりということはあまりやってほしくないのだけれども。

ところで、HTML5の仕様から削除されたものはhgroupだけではないらしく、menuタグやcommandタグというものもあるよう。ただし、こちらはHTML5.1の仕様へ移行という形になっているようです(参考:HTML5 勧告候補が更新、menu / command 要素などが削除 | WWW WATCH)。

また、hgroupについて調べていると、かなり詳しくhgroupについて書いてあるサイトを発見(HTML 5での<hgroup>要素について(平成22年 3月 8日) – 『しらぎくのWWW作成入門』メモ)。なんだか悲しくなってきた。

こうやって調べてみると需要はあるように思うのだけど、何で削除したんだろう。

ブラウザからデスクトップ通知をする方法


久々に、HTML5 テクニックバイブルで知ったことのメモ。いったい何度目だ・・・。

今回はデスクトップ通知について。なんと、HTML5では、ブラウザからデスクトップ通知を表示することができるそうです。しかも、通知を指示するページを表示してなくても(ブラウザを最小化してたり、別タブで違うページを見てたりしててもという意味)。

とりあえず、サンプルページとして、カウントダウンタイマーを作成して0秒になった時点でデスクトップ通知を表示するウェブページを作ることにします。

サンプルページ:
最新のChromeやFirefoxではうまく動くはずです。

ページを開くと『デスクトップ通知を有効にする』というボタンが表示されていると思うので、そのボタンを押し、デスクトップ通知の許可をしてください。その後、スタートボタンが押せるようになると思うので、分と秒の数値を指定し、スタートボタンを押してください。カウントダウンがはじまります。0秒になるとデスクトップの右下に通知が表示されます。

試しに10秒ぐらいで試してみて、ブラウザを最小化したり、別タブを見たりしてみてください。それでも表示されると思います。なお、通知をクリックすると通知元のページを表示するようにしています。

canvasで描いた絵をバイナリ形式でサーバーにPOST送信する方法


最近、自宅で時間ができるとHTML5 テクニックバイブルという本を読んでいるのですが、初めて知ったことがいろいろ書いてあって驚愕する日々を送っています。

今回は上記書籍を読んで知ったCanvasで描いた絵を、Base64のData URI形式ではなく、バイナリ形式にしてPOST送信する方法のメモ。ただし、IE9では使えないよう。

まずは、受け取り側のPHPを記述。普通にフォームの画像ファイルを受け取ってサーバーにファイルを保存するような記述を書いておきます。ファイルのアップロード | PHP Laboを参考にしました。

上記のPHPでは、acceptImageというプロパティに対応するファイルをtest.pngという名前で保存するようにしたPHPです。試しに、下記のようなHTMLを書いて普通にファイル選択してPOSTするとうまく動きました。

というわけでつづいて、前に作ったCanvasお絵描きツールの投稿先を、上記PHPに変更し、JavaScriptでCanvasのデータをPOST渡しできるよう記述するように投稿ボタンを押した時の処理を下記のようにしてみました。

実行サンプル:canvasを使ったお絵描き投稿システム

HTML5 テクニックバイブルのほうでは、jQueryを使わずに純粋にXMLHttpRequestオブジェクトを使ってAjax送信しているコードが載っていたのですが、自分は最近Ajaxを使う時はjQueryを使うことにしてるので、jQueryを使って書いてみました。実はjQueryを使ったAajxでは最初うまく動かなかったのですが、調べてみるとjQueryでFormDataオブジェクトをAjaxで送信する場合には、contentTypeとprocessDataをfalseにしなければいけないと分かり、そのオプションを変更することによってうまく動きました(参考:jQuery: FormData オブジェクトで送信する – Sarabande.jp)。
HTML5テクニックバイブルに載っているコードでは、そんな記述が必要ない分、もう少しシンプルな記述となっています。

それにしても、上記コードは自分が初めて知ることがたくさんあります。FormDataオブジェクトぐらいなら聞いたことはあったのですが、BlobオブジェクトとかArrayBufferオブジェクトとかUint8Arrayオブジェクトとか、何だそれ!? という思いです。簡単に説明すると、BlobオブジェクトはMIMEタイプを含んだバイナリデータを表し、ArrayBufferオブジェクトは固定長のバイナリデータを表し、Uint8Arrayは8ビットの符号なし整数を表すようです。なお、Uint8Arrayの説明には、C言語での同等タイプに『uint8_t』という記述が。そんなデータ型がC言語にあったか? と思って調べてみると、どうやら『unsinged char』と同じらしいです(参考:整数型 – Wikipedia)。

HTML5はある程度知っているつもりでいましたが、まだまだ知らないことが多くありそうです。

ところで、Blobオブジェクトの取得については、canvasオブジェクトにtoBlobメソッドが実装されていれば、そのメソッドを使うことにより、簡単に取得できるようです。ただ、このメソッドは残念ながら、Firefoxでしか実装されていないよう。html5.jpによると、2011年4月5日の草案にはすでに提案されていたようなんですが・・・(参考:W3C – 『HTML 5 differences from HTML 4』日本語訳 – HTML5.JP)。Chromeですら実装してないとなると、さすがに使うのに躊躇します。

canvasのお絵描きツールに『戻る』『進む』ボタンをつけてみる


描き間違いがあったときに一つ前の状態に戻る機能がほしくなったので、その機能を追加することに。とりあえず、五回分を保存できるようにしてみた。塗りつぶし機能よりは簡単に実装できました。

以下、JavaScriptのコード

以下、動作サンプル。
canvasを使ったお絵描き投稿システム

saveImageDataという関数は、初期状態やキャンバス上でマウスボタンやタッチが離された時に実行するようにしています。やっていることは単純で、17行目のgetImageDataメソッドで現在のキャンバスの状態をimageMemory という配列に保存し、戻るボタンや進むボタンをおした時に現在の番号(flagMemory)の前や次に対応したimageMemoryに入っているキャンバスのデータをputImageDataでキャンバス上に描画しています。
何度か戻った後に新しくキャンバスに絵を書いた場合、次の画像というものがないのが自然な気はしますが、わざわざ消す必要もないだろうと思い、消してません(面倒だっただけだろと突っ込まないでください)。

なんというか、本当思いついたらその分追加するだけのコードになっているので、汚い気はします。もっとキレイなコードを書けるようになりたいです。