jQueryConceptual:EXIFviewerに撮影地の地図表示機能を追加コメントをどうぞ予告通り、ローカル領域にあるjpegファイルのEXIF情報を表示するWEBサービス、EXIFviewerの機能を追加してみた。Mapsで表示するというもの。APIと連携する際の注意点が中心となる。APIに渡すには、JavaScript(jQuery)を使ったクライアントサイドでの値取得が必要となる。そのため、値の入ったセルにidで一意の名前をつけるようにする。前回手を付けられなかった値のサニタイジングもついでに行う。"画像のEXIFデータが見つかりませんでした。"画像をセットして下さい。"画像のEXIFデータが見つかりませんでした。"画像をセットして下さい。画像のEXIFにGPSの情報が不足なく入っていた場合に初めて処理を行うようにするので、このPHP部分で情報の不足をチェックし、地図表示の実行フラグとして非表示のセルにでも入れれば、JavaScript側の記述がスマートに済む筈。今回それをしなかったのは、不特定多数が利用する可能性があるため、出来るだけサーバ側の負担を軽く、クライアントサイドで処理を担保してもらうように設計したため。APIを使いたい場合、htmlのヘッダ部で読み込む事になる。</head>こういった具合。クエリストリングのsensor=falseという部分は、利用者の位置情報を求めるかどうかということで、falseに設定しておけば鬱陶しい確認ダイアログが出ないだろう。今回は、id=”googlemapdiv”というdiv要素の中にマップを表示する場合で説明する。jQueryのreadyの中に、以下のように記述した。});コントロールの指定については必須ではない。google.maps.Mapメソッドに引数として地図の設置場所(DOMオブジェクトで指定)と、各種オプションを代入する。APIに渡せば良い、、とはいかない。APIが受け付けるのは10進法の数字なのだ。そこで、画像から取得した緯度経度を60→10進法に変換する処理を用意しないといけない。60→10進法変換の方法だが、たとえば60進法で12.3という数字があった場合、10の位の1は10進法の60*1を表し、1の位の2は1*2、小数点第一位の3は60分の1*3を表している...といった数学の知識を、思い出してほしい。iPhoneなどが採用している60進法の表示方式では、”北緯36度46.5分0秒,東経137度54.52分0秒”といったように書くが、これは成形された表ではこのように表示されている。EXIFでの緯度経度GPSLatitudeRefやGPSLongitudeRefが東西南北(EWSN)を表している事は分かり易い。0が表すのは、緯度の”度”の部分。”36/1′′という数字は、分母が1で分子が36ということ、つまり分数だ。1は100分の4650、つまり46.5分を表すといったように、面倒臭い書き方をしている。この値が60進法なのだ。変換手順は、分数の文字列をなんとか少数に直して、それから10進法への変換を行うという形になる。最後に10進法に直した後の値に、西経、南緯の場合マイナスをつけるという手順も必要だ。}このようにして出てきた結果を、google.maps.LatLngメソッドの引数として与えてやれば良い。いうことで、EXIFViewerでの地図表示が可能になった。労力のわりに、いまや出来て当たり前の機能のように見えるからどうにも報われないのです。adminPHP、JavaScriptそれぞれにおける無名関数コメントをどうぞPHPとJavaScriptを同時に使って開発を行う事が多いという個人的事情のため、混同しないようにする目的で書いているこの比較シリーズですが、今回は無名関数について扱います。無名関数というのは、関数的な処理のまとまりを、名前空間を消費することなくアドホックに定義する手法で、最近ではajaxなどの通信を伴う関数の、コールバック関数として使われるのが一番身近な使用と言えるかもしれません。無名関数使用例の紹介もかねて、PHPとJavaScriptそれぞれの無名関数の書式を見てみましょう。以前、spl_autoload_register関数の説明で用いた例です。});なにやらjQuery方面でよく見かけそうな、中括弧と小括弧の連続です。無名関数を使っているのはspl_autoload_register関数の引数の部分で、したがってfunctionの前の”(“と最後の”)”は、無名関数の書式とは関係ありません。通常の関数定義を関数名を抜かして行えば無名関数になるわけですね。無名関数の即時実行なお、定義した無名関数に値を与えて即時実行する場合、可変長引数を関数内で引き渡す記事の際に使ったcall_user_func_array関数、もしくはcall_user_func関数を使います。//無名関数の即時実行//call_user_func(関数名,引数)という書式でしたね。//call_user_func(関数名,引数)という書式でしたね。},"dullFunction");PHPの無名関数の注意点としては、無名関数が使用可能なヴァージョンが5.3以降と、比較的最近実装された機能だという事です。現在稼働中のプログラムでも、5.2系のヴァージョンで作成され今まで運用されているものが結構ありますので、その場合無名関数は使えないので注意です。基本的な書式JavaScriptを使ったajax開発では、無名関数が頻繁に登場します。以下はjQueryの$.ajaxでコールバックとして無名関数を登録する例です。});successのラベル以降が無名関数の使用になります。PHPのものと、変数に$が付くか付かないか程度の違いしかありません。無名関数の即時実行について、JavaScriptは専用の関数を持っていません。かわりにより簡潔な書き方で即時実行をすることが出来るようになっています。})(anydata);通常の無名関数の宣言との違いは、関数名にあたる部分を括弧でくくり、また関数の実行なので最後にセミコロンをつけているだけです。即時実行の利用頻度は低いかもしれませんが、ソースコードの中に急に出現した括弧付きの無名関数宣言に、当惑してしまわぬよう頭の片隅に入れておくとよろしいでしょう。adminPHPとJavaScriptでURLのクエリストリングを評価するコメントをどうぞクエリストリングというのは、ほうぼうのWEBサービスでよく見かける、URLの後ろについた情報を持った文字列です。して、URLにユーザ検索の内容をつけて遷移後のページに渡しています。このクエリストリングは、search_queryのような普遍的な語でなくても、勝手な語を選んでつけることができます。そもそも、HTMLでフォームを作って送信方法にGETを選ぶと、input要素のユーザが設定したname属性がストリングになっていますね。input要素が複数の場合は、&で結ばれています。これもクエリストリングの特徴です。このクエリストリングをプログラム側でキー値と値の組で取得するにはどうすればよいでしょうか。PHPでクエリストリングPHPの場合、大抵の文字列操作は標準の関数として装備されています。自分で作る前にまず探してみると、大抵便利なのがあります。再発明した車輪はゴミの日にそっと出しましょう。//$arr["query2"]は値23で$arrを指定しなければ、通常の変数($query1,$query2)にそれぞれの値が入ります。JavaScriptでクエリストリングJavaScriptの場合には、車輪の開発者になる余地が大いにあります。PHPのような標準でクエリストリングを扱う関数が無いのでしょう?簡単な話です。JavaScriptは未来の言語だからです。//arr["query2"]は値2こういった具合です。実はJavaScript自体の関数ラインナップはPHPより劣るものの、PHPと同様の充実度を誇るのがjQueryです。確実に世界のどこぞの誰かが、あなたより先に車輪を開発してプラグインにしています。クエリストリングの評価ならば、jquery.toObject.jsこちらを使えばよろしいでしょう。こんな何某のWEB制作日記とか言う場末ブログのブックマークは、今すぐゴミ箱に放り込みましょう。FileReaderを使った画像のドラッグ&ドロップアップロードコメントをどうぞHTML5で新たに搭載されたAPIを利用して、WordPressのメディアアップロード画面のようなドラッグ&ドロップでの画像アップロード機能を実現します。URLの保存方法を説明します。STEP0:HTML5におけるページ内要素のドラッグ&ドロップHTML5では、ブラウザ上でのネイティブのドラッグ&ドロップを実現させるための属性として、draggableおよびdropzoneが用意されました。理想的には、draggable=”true”と指定されたページ上の要素をぐぐっと掴んで、dropzone属性の指定がされた要素の上に移動できるという動作の実現が期待されているのですが、dropzone属性に対応しているブラウザがほぼ無いため、ドロップ側の挙動はJavaScriptで実装するしかありません。JavaScriptは置いておいて、属性指定だけした動作サンプルを見てみましょう。draggable=”true”を指定した要素(対応ブラウザならぐぐっと掴める)dropzone=”move”を指定した要素(対応ブラウザならドラッグした要素をドロップで受け付ける)これがページ内要素のドラッグ&ドロップです。動作していないでしょう(笑)。ちなみにdropzone属性の値は、ドラッグ中の要素を移動させる”move”以外にも、複製する”copy”、ドラッグされた要素のリンクを取得する”link”などがあります。STEP1:ローカルファイルのドラッグ&ドロップ今回作成するプログラムのように、ローカルファイルをドラッグ&ドロップする場合には、ドラッグ側にdraggable属性を設定しなくてもOS標準機能でドラッグができています。通常ブラウザ上にファイルをドロップしたときの処理は、例えば画像ファイルやテキストファイルであればウィンドウ全体を使ったプレビュー表示になりますので、この標準処理をドロップ側でキャンセルし、別の処理をイベントに紐づける必要があります。JavaScriptを使うことになります。STEP2:ドロップを受け付ける要素を用意してAjaxイベント付加では、ドロップを受け付ける要素にdropzone属性の代わりとなるイベントをつけましょう。//jQueryのCDNでのインポート。ヴァージョンはあまり気にせず。//ドロップを受け付ける領域は、適当にclass名をdropzoneとしておく。function(data){//成功処理を書くならここに。handleDroppedFile);}});</script>//jQueryのCDNでのインポート。ヴァージョンはあまり気にせず。//ドロップを受け付ける領域は、適当にclass名をdropzoneとしておく。//成功処理を書くならここに。</script>dropzoneには$.bindでもってイベントを結びつけます。ここでは”dragover”,”dragenter”,”dragleave”,”drop”の4種類が出てきますが、領域にファイルが重なったときに処理を行わないのなら、”dragover”と”drop”だけで良いでしょう。dragoverでは、ファイルをブラウザのウィンドウ上にドラッグしたときの標準処理をpreventDefaultでキャンセルし、stopPropagationでイベントが下位要素にも伝わってしまうのを止めます。true;)ようです。IE10ではFileReaderがサポートされるみたいなので、対応の手間が増えますね。fileReaderからreadAsDataURLでファイルをDataURLにする辺りは、以前OnlyCSViewを作成したエントリを参考。今回は$.postではなく$.ajaxを使っているので注意です。URLにされた画像の解凍に一手間が要ります。//とりあえず一意の名前になってほしいので、日付時刻をコピー先ファイル名にする。//とりあえず一意の名前になってほしいので、日付時刻をコピー先ファイル名にする。?>エラーのコールバック処理を入れなければこういう感じです。URLのbase64エンコードを解凍するのですが、このときURLのファイルタイプ部分を取り除いてやらないと、PHP側でうまくコピーできないというのがキモですよ。adminさらっと理解しておきたいjQueryオブジェクト(後編)コメントをどうぞ前編からひっぱります。JavaScriptのオブジェクトについて、組み込みオブジェクト、ブラウザオブジェクト、DOMオブジェクトの三項目について説明しましたが、これらのオブジェクトではピリオドで何個もの処理を繋ぐメソッドチェーンの書式が使えません。メソッドが返す返り値が文字列や数値などバラバラな型であるからで、それは手続き型プログラミング言語のメソッドとして何ら不思議なことではありません。HTML文書の要素を対象とした操作をする場合、一度処理を行った要素に連続して処理を与えるというケースが非常に多く、その度に要素の検索を行うのがかなりのオーバーヘッドとなります。そこで、メソッドの結果がまたオブジェクトを参照することで連続して処理を与えることのできるメソッドチェーンの実現に意味があるのです。jQueryの要素の多くは、自身jQueryオブジェクトである上に、処理の返り値としてもjQueryオブジェクトを返します。jQueryオブジェクトとは何かというと、セレクタにより検索、ヒットしたDOM要素の集合を、多数の便利なメソッドの定義されたオブジェクトでラップしている状態です。console.logなどでオブジェクトの中身を確認してみると、単なる文字列として格納されたHTML要素と、ずらりと並んだプロパティ、メソッドがあることがわかります。これらのセットがjQueryオブジェクトです。メソッドチェーンの終端で、jQueryオブジェクトのメソッドでない、通常のDOMオブジェクトのメソッドを使いたい場合はどうすれば良いでしょうか。前編で出した動かないプログラムの例ですが、jQueryオブジェクトの正体を知っていれば、このようなアクセスが可能であると予想が立ちますね。"Hi!";このように、呪文のようなjQueryと言えども仕組みがわかれば何ということも無いのです。これはjQueryのセレクタエンジンにも言えることなのですが、それはまたいずれかの機会に記事にします。adminさらっと理解しておきたいjQueryオブジェクト(前編)1件のフィードバックCSSコーダにとって、サイトを動的にしたい時の救世主となるjQuery。CSSセレクタで要素を選択し、あとはメソッドの書式に従っていくつかの呪文を唱えるだけで、簡単にアニメーションや文書構造の変更ができます。サイト訪問時にclass=”fadein”とした全要素をフェードインする場合、以下のようなソースで事足ります。li”)のような指定にも対応していますので、解説サイトのサンプルをコピーして、セレクタ部分を変更するだけで好きな要素に処理を適用できます。同じ要素に対して複数の処理を連続して適用する場合には、処理を順番にピリオドで繋いでいけばよいという特性も直感的です。メソッドチェーンと呼ばれるこの書き方を頭に入れておけば、JavaScriptについてほとんど知識が無くても、処理部分に手を加えることができます。//フェードイン後フェードアウトこうした直感的な文法をもつjQueryですが、本当に直感のままの記述を行っていると、ときどき反逆します(笑)。メソッドチェーンが有効にならず、途方に暮れてしまいます。//動きませんあるいは、JavaScriptについて少し知識のある人間が、jQueryもJavaScriptだからとチャンポンな書き方をして反逆されることもあります。//動きません何故こういったことが起こるのか、結論から言いますと、jQueryは独自メソッドをもつjQueryオブジェクトというオブジェクト形式を扱う為で、メソッドチェーンなどもメソッドの返り値がこのjQueryオブジェクトである為に実現しているのです。jQueryオブジェクトを知る為に、JavaScriptのオブジェクトの種類について整理してみましょう。〜素のJavaScriptが持つオブジェクトJavaScriptというと、WEBページを動的にする手段としてWEBと切っても切り離せない言語であると思われがちですが、実際のところ素のJavaScriptがそういった機能を有しているわけではありません。ブラウザ以外のJavaScript実行環境で、document.writeIn()などと命令しても、JavaScriptはそれがどういう命令なのか理解する事ができません。それでは素のJavaScriptはどのような要求に応えるのかというと、数値や文字列の演算であったり、メモリへのアクセスであったりと、プログラミング言語の基本的な処理です。素のJavaScriptにもオブジェクトやメソッドといった概念があり、既に組み込み済みのオブジェクトもあります。Stringオブジェクトは文字列を操作するメソッドを提供するオブジェクトで、このオブジェクトは特に宣言をしなくても、文字列データに対して自動的に呼び出すことができるようになっています。//titlelengthの値は5この例では変数movieに入った文字列をStringオブジェクトで自動的にラップしているため、Stringオブジェクトのlengthメソッドを使う事ができています。他にも組み込みオブジェクトとして、NumberやArrayなどがあります。〜ブラウザメーカーによる勝手実装のオブジェクトJavaScriptがWEBページを処理の対象として認識できるのは、WEBブラウザがJavaScriptのオブジェクトとしてページを定義し、処理の為のメソッドを提供しているからです。具体的にはページはWindowオブジェクトとして定義され、Windowオブジェクトの直下にdocument、location、navigatorなどのプロパティがあり、これらもまたオブジェクトとして定義され、メソッドが提供されているといった構造です。基本的にこのWindowオブジェクトは省略して書く事ができるため、おなじみのdocument.writeIn()という表記になっているわけです。ちなみにWindowオブジェクト自体のメソッドとしては、setTimeOutなどのタイマー系やalertなどのウィンドウ表示系があります。これらは確かにdocument.alert()のようには書きませんね。documentオブジェクトは下位にforms、images、anchorsといったオブジェクトを持ち、これらのオブジェクトはページ中のフォーム要素、イメージ、アンカー全てを配列に格納してくれているので、name属性やインデックスで個々の要素を取り出す事ができます。document.イメージ名.src;このように基本的なオブジェクトモデルをベンダーが定義してくれているおかげで、JavaScriptがWEB制作の言語として特待的なポジションを得ているわけです。ブラウザオブジェクトはIEとNetscapeのブラウザ戦争の過程で、独自仕様を実装しよう(そして囲い込みを行おう)という目論見のもとにルール無用に拡張されていった背景があります。そこで、そうした勝手実装でなくどのブラウザでも共通した記述が可能になるようなオブジェクトモデルが求められるに至りました。Modelの略で、HTMLの親戚であるXMLを操作するための汎用モデルです。ブラウザオブジェクトの勝手実装による混乱に収拾をつけるため、W3Cはこのモデルをベースにしたオブジェクトやメソッドを定義し、勧告としました。DOMオブジェクトは文書中のhtmlタグとその属性、テキストなどに対応し、メソッドやプロパティを持ちます。各タグへのアクセス方法として、タグ名、id、クラス名での検索メソッドを提供しています。これらはブラウザオブジェクトのdocumentオブジェクトをhtml文書の最上位の要素<html>の参照というかたちで実装されているので、これまでのブラウザオブジェクトのスクリプトと併存して使う事ができます。今回はjQueryオブジェクトの説明まで辿り着かなかったので、次回に続きます。adminSafari、Chromeで動くJavaScriptがFirefoxで動かない→宣言部、ヘッダ部を疑いましょう3件の返信JavaScriptが満載のWEBページを制作していて、ページの一部の機能がSafari、Chromeでチェックした際には動作するのに、Firefoxでは全く動作しないという状況に遭遇しました。具体的には、ナビゲーションボタンのマウスホバー時の挙動として、透明度の指定をjQueryで行った箇所と、画像のLightBox的挙動のためjQuery.lightboxを使った箇所です。functionというエラーが表示されます。lightboxのエラーは、画像が拡大表示された後ページに戻る事ができず背景が暗いままという不具合で、こちらは特にコンソールに表示はありません。これはjQueryの動作に問題があるのだろうとあたりをつけ、様々な手段を使ってチェックを行いました。ホバー部分のコードについては、以下のようなものでした。</script>hoverメソッドは引数に関数を二つ取り、それぞれホバー時と終了時の処理を書く事ができます。処理の部分で、fadeToではなくcssメソッドを使ってopacityを指定するも動作せず。cssメソッドでwidthなどの他の値を指定する場合は動作します。透明度関係の指定が上手く行っていないということが予想できます。そこでブラウザのopacityの実装の違いではないかと考え、Firefoxについてのリファレンスを漁ったり、懐かしの-moz-opacityを引っ張り出してきたりと、色々と試みるも挙動が変わる事はありません。次にプラグイン同士の相性を疑い、抜き差し抜き差しするも効果なし。jQueryのファイル名やヴァージョンの変更を行うも駄目。この時点で既に大量の時間を原因の究明に費やしています。戯れに同じコードを別の製作中のページに貼付けてみると、ちゃんと動作しました。そのページはXHTMLではないHTML5のページだったので、jQueryやlightboxプラグインのドキュメントをあたり必須要件がHTML5なのかチェック、しかしながら特に指定はありません。/>こんなに単純な事でした。本来Content-Script-Typeでtext/javascriptを指定しなければならないところを、上のcssの指定をコピーしてそのまま、Content-Style-Typeとしていたわけですね。HTML5で無事に動いたのかというと、これらの部分が省略可だからでした。トラブルを一般化すると、SafariやChromeで動くJavaScriptがFirefoxで動かない場合、間違ったXHTMLの記述に対する、ブラウザの解釈の違いが原因である場合があるということです。一字一句間違えてはならないDOCTYPE宣言についても、思わぬエラーの原因になりそうなものです。実際標準モードと互換モードでcssの解釈が異なるので、意図せず互換モードが呼び出され、jQueryでの表示不具合に直結している可能性があるのではないでしょうか。毎度の事ですが、ニッチなエラーに足を取られ易い私の失敗談が、誰かの役に立てば幸いです。初心者JavaScripter、jQuery使いにオススメ。JavaScriptの曖昧な理解をなくしておこう。]価格:2,919円(税5%込、送料込)WordPress案件でも戸惑わない!「WordPressで作ってくれ」という案件や、既存WordPressサイトの拡張案件などで、PHPerが戸惑わないための本。WordPress関数やテンプレートファイルの構造、フックの概念の説明など。]価格:2,940円(税5%込、送料込)たまにでいいからActionScriptを思い出してくれ...FlashとActionScript3.0。しても使わなければならない仕事のときに。ActionScriptライブラリにときめいた時代を思い出せて、しかも実用的な本。さようならFlash。]価格:2,940円(税5%込、送料込)iOSアプリ開発新言語Swift畑違い?いやPHPやJavaScriptに飽きたら、ぜひモダン言語の風を。