[ カテゴリー » 開発日誌 ]

HTML5によるファイルアップロードスクリプトの配布

category-icon

 おはようございます、martinです。前々回ぐらいに、HTML5を用いたプログレスバー付きのファイルアップロードのデモを示しました。この手のスクリプトは、プログレスバーの表示にFlashやJavaを用いていることが多いのですが、ファイルサイズが大きくなる傾向になったり、設置がややこしかったりします。

 何件かソース希望のリクエストがあったので、ppBlogからのスピンアウトとして配布しようと思います。配布するやつは、PHPとJavaScript(+CSS)だけでプログレスバーを実現していて、設置も比較的簡単ではないでしょうか。添付ファイルを展開すると以下のファイルが含まれています。

  • index.html(ここにアクセス)
  • fileUpload.php(PHPでのファイルアップロード処理用)
  • oParts.js(プログレスバーのためのJSライブラリ)
  • progressbar.png(プログレスバーの画像)
  • PIX(アップロードした画像を保存するフォルダ)

 基本的には、展開したフォルダを然るべき場所にまるごとアップロードして、index.htmlにアクセスすればOKかなと思います。サーバーによっては、PIXディレクトリのパーミッションの指定が必要かもしれません(707とか)。

 画像を保存するディレクトリは、PIXにしていますが、これは適当に名前を変えても良いでしょう。fileUpload.phpの最初の方で指定出来ます。

$pix_dir = 'PIX/'; // 画像を保存するディレクトリ。パーミッションは707とか。

 うまく動けば、アップロード中は以下のような画面になっているかと思います。

shot

*あくまでサンプルです。最低限の実装なので、セキュリティ関連は、各自でいじって下さい。JavaScriptをいじれば、プログレスバーに加えて、全体の何パーセントが完了みたいなことも出来るでしょう。

添付ファイル: MultipleFileUpload.zipattachedIcon 

     


— posted by martin at 02:29 pm   commentComment [0]  pingTrackBack [1]

HTML5による複数ファイルアップロード

category-icon

 こんばんは、martinです。以前、Flex(Flash)を用いた複数ファイルのアップローダーLink を紹介しましたが、実はHTML5だけで出来るのになぁ、と思っていました。現時点で、IE8を除く主要なブラウザでは軒並み、HTML5のINPUT要素に対するmultiple属性に対応しているので、それによる実装をppBlogに施してみました。複数ファイルを選択可能にするには、input要素にmultipleを指定するだけです。

<input type="file" name="src[]" id="src" multiple />

 とりあえず実装してみただけですが、きちんと動作しました(ここのエントリーLink は画像を複数枚一度にアップロードした)。UIをどうするかで試行錯誤しましたが、プロトタイプにしてはまぁまぁかなと思っています。

shot1
このように一度に複数画像の選択が可能です。

 さて、複数の(画像)ファイルがアップロード出来るようになると、アップロードする枚数に応じて、サーバーにデータを渡す間、じっと待たされるようになります。現状、HTML5のみではぼーっと待つしかありません(-o-) なので、アップロードの進捗状況を示すプログレスバーが欲しくなります。この手のスクリプトはウェブ上にいろいろありますが、どれもFlashを用いたり、Perl(+JavaScript)を用いたりしたものです。出来ればPHP(+JavaScript)のみで完結させたい。

 いろいろ調べてみると、PHPとJavaScriptのみでは、ファイルアップロードに伴なうプログレスバーのギミックを提供するのは無理という記述ばかりです。というのもPHPには、ファイルアップロードの途中経過を知らせる仕組みが備わっていないからです。実は、PHP5.2以上であれば、PECL APC拡張機能を組み込んで可能Link なのですが、サーバー側で PECL APCエクステンションをインストールする必要があり、これはレンタルザーバー等では敷居が高いでしょう。

 なので(Perlはあまり好きになれないという理由もあり)PHPとJavaScriptのみによる実装を考えてみました。まずは、PHPにおける、POST メソッドによるファイルアップロード時の挙動を知る必要があります。マニュアルによれば、基本的に以下の手順を踏みます。
  1. サーバー上に転送される(画像)データは、最初は一時的なディレクトリ(テンポラリディレクトリ)にアップロードされます。この一時的なディレクトリは、だいたい/tmpディレクトリのことが多いです。php.iniで指定可。
  2. 画像データの転送が無事に終わると、move_uploaded_file関数を用いて指定したディレクトリに画像データを移動させます。

 PHPでのネックは、この1番目の進捗状況を知るメソッドが備わっていないことです(なのでこの部分だけはPerlで処理するスクリプトがある)。サーバーサイドで提供しないのであれば、こちらからゲットしに行きましょう。アップロード中のデータは、テンポラリディレクトリに溜まっていくので、そのディレクトリのサイズは徐々に大きくなるはずです。なので、そのディレクトリのサイズを定期的に監視すればOKということになります。この「定期的に監視」という部分にJavaScriptのAjaxを使えば良いわけです。

 ディレクトリのサイズは、以下の記述で取得可能です。
$tmp_dir = '/tmp'; // 取得したいテンポラリディレクトリ

$size = 0; // ディレクトリのサイズ

$d = opendir($tmp_dir);
while($file = readdir ($d)){
 if(is_file($tmp_dir.'/'.$file)){
  $size += filesize($tmp_dir.'/'.$file);
 }
}
closedir($d);
echo($size); // ディレクトリの合計サイズを得る

 なお、上の例では、テンポラリディレクトリは/tmpですが、これを取得したい場合は、ファイルアップロード時に現れる変数の$_FILES['src']['tmp_name']を利用して、

dirname($_FILES['src']['tmp_name']);

で取得可能です。

 あとは、AjaxとPHPで、このディレクトリサイズを返すような記述をして、それをJavaScript側に渡し、プログレスバーっぽく見せればOKとなります。具体的なデモLink を見てみましょう。うまく行けば、転送中のブラウザ画面は下のようなスクリーンショットになります。Firefox3.6.3Safari, Google Chromeの最新版で動くと思います。

progressbar
プログレスバーが表示され、進行状況が一目瞭然。

       


— posted by martin at 01:14 am   commentComment [6]  pingTrackBack [0]

IE9ではDOMContentLoaded をサポートするようだ

category-icon

 こんにちは、martinです。久しぶりの書き庫な気がします。

 IE9のプラットフォームプレビューLink が出ていたんで、インストールしてみました。最初に試したことは、他の主要なブラウザでは実装済みのDOMContentLoadedがサポートされているかなぁ、ということでした。現時点では、まだでしたが、IEBlogLink によると今後のロードマップに、DOMContentLoadedのサポートがあるようです。DOMContentLoaded自体は、DOM Level 3 Eventsには定義されていないので、IE9が標準仕様に忠実であろうとするならば実装は微妙だなぁ、と思っていたんですが、HTML5には定義されていますLink (注意: リンク先はかなりページが重い)ね。

 IE9でDOMContentLoadedがサポートされるのはまことに喜ばしいことですが、IE9が普及するのはまだまだずっと先の話でしょう。なので現状では、IE向けにはDOMContentLoaded相当の機能を自前で実装する必要があります。世の中には、jQueryを始めとした便利なJavaScriptライブラリーがいくつかありますが、猫も杓子もDiego Perini氏が発見したdoScrollメソッドを使う手法Link に則っています。ppBlogでのoParts.jsでも、doScrollの実行をもって、DOMパース完了とみなすやり方で実装しています。

 さて、このdoScrollメソッドですが、MSDNの説明にあるように、

The doScroll method is available on all objects, regardless of whether they support scrollbars.

引用元: doScroll Method (A, ABBR, ACRONYM, ...)Link

 ほぼすべての要素について適応可能です。多くのJavaScriptライブラリーでは、

document.documentElement.doScroll('left');

 というふうに、document.documentElementに適用しているケースが殆どですが、何でも良いので、以下のようなやつもOKです。

(function(){
  if(navigator.userAgent.match(/MSIE/)){ // IEなら
   try {
     new Image().doScroll(); // new Imageオブジェクトについて適用
     onReadyFunc(); // DOM構築後に最初に呼び出す関数
   } catch(e){ setTimeout(arguments.callee, 1);}
  } else { // IE以外
   document.addEventListener("DOMContentLoaded", onReadyFunc, false); // DOM Level 3 Events相当
  }
})();

 別にnew Imageオブジェクトをdocument.bodyappendChildする必要もありませんし、メモリーリークも起こしません。以下のようにコメント文を生成するメソッドcreateComment()を用いても良いでしょう。これも、既存の文書に作ったコメントをappendする必要はなく、ただ宣言するだけで動きます。

(function(){
  if(navigator.userAgent.match(/MSIE/)){ // IEなら
   try {
     document.createComment().doScroll(); // document.createCommentについて適用
     onReadyFunc(); // DOM構築後に最初に呼び出す関数
   } catch(e){ setTimeout(arguments.callee, 1);}
  } else { // IE以外
   document.addEventListener("DOMContentLoaded", onReadyFunc, false); // DOM Level 3 Events相当
  }
})();

 doScroll()の引数は省略可能です。省略するとscrollbarDownが適用されるので、document.documentElement.doScroll()だと、実際に画面がスクロールしてしまうかもしれません(なのでたいてい”left”を指定している)。new ImageやcreateCommentだと、DOMツリーに追加するわけではないので引数は省略して構いません。

 new Image().doScroll()なんて、短い記述で済むんでいいなぁ、と思うけれど。

 


— posted by martin at 09:50 am   commentComment [2]  pingTrackBack [0]

CSS3のtransformをIE8でも使いたい

category-icon

 こんばんは、martinです。FirefoxやWebKit系のSafari、グーグルのChromeなどは、CSS3の魅力的な機能を色々取り入れています。中でも、CSS3のtransformLink やドロップシャドウ系は、ブログで写真を見せる場合などに凝った演出が出来るので、仕様が正式に決まるのが待ち遠しいですね(そう言えば、ボックスのドロップシャドウ box-shadowですが、CSS3の勧告候補から消えたLink のかなぁ)。便利な仕様だとは思うのですが。

 ちなみに、transformとは「変形」のことで、CSSのみで画像やらボックスやらを自在に回転させたり、ゆがませたりできる優れものです。で、例によってIE系はCSS3の対応は遅れています。とは言っても(これまたいつものように)transformに関しては、IEは実にIE5.5の時から似たようなものを実装していましたLink ! なので、それらを駆使すれば、CSS3相当のtransformが実装できそうです。

 transformが使えると何がうれしいって、例えば以下のようなポラロイド写真みたいなギャラリーがCSSのみで簡単に出来ます。実は下のショットはIE8でのものです。
CSS3-transform-IE8
IEでもCSS3のtransform相当のことが出来る

 画像の回転に関して、FirefoxやWebKit系は、画像の中心を回転軸として回転させます(なので回転軸は移動しない)。これは直感的で分かりやすいです。これに対して、IEは回転軸が指定した回転角度によって刻々と移動します。なので、標準仕様に似せようと思うと、回転軸を動かさない様にするための補正計算が必要になります。この計算にちょっとてこずりましたが、何とか回転軸が動かないような補正をすることが出来ました。

IE rotation
IEでは、ボックスはx軸とy軸に2点が常に接しつつ、すべるように回転するので軸が常に動く。

 で、とりあえずモノになりそうなものが出来たのでデモサイトを挙げておきます。画像へのマウスオーバーで拡大なんてのもCSSのみで出来るのですが、それもIEで動くようにしています。

 

→「CSS3 Transformを使ったギャラリー(IE互換)Link

 FirefoxやSafariでは、完全にCSS3のみで実現していて、IEでは、IE特有のフィルター機能をJavaScirptを通して操作しています。ボックス要素のドロップシャドウについては、以前、まぁまぁ凝ったスクリプトを書きましたLink が、新たに要素を追加しないといけないなど、あまり納得のいくものではありませんでした。今回ドロップシャドウに関しては、あまり凝ることはせずに、IEのフィルター機能を素直にそのまま使っています。
progid:DXImageTransform.Microsoft.dropshadow(enable=true,OffX=3, OffY=7, Color='#11000000', Positive='true');

 実は最近知ったのですが、フィルターのColorには通常のRGB形式だけでなく、透明度も指定できる#AARRGGBBの形式が使えるので、黒色の透明度を高くすればより影っぽくなります。CSS3レベルのぼやけた感じまでは出ませんが、まぁ、これで良しとしましょう。

 使い方は、簡単で、形はHTCファイルですが、JavaScriptの外部ファイルとして動作するようにしてます。これは、以前のドロップシャドウのスクリプトと同じです。それをIEのみが解釈する条件コメントの中に書いています。
<!--[if IE]>
 <script type="text/javascript" src="js/css3transform.htc"></script>
<![endif]-->

 これを書いておくだけで、スタイルシートに記された

     -moz-transform: rotate(-2deg);
  -webkit-transform: rotate(-2deg);
          transform: rotate(-2deg);
などを解釈して、IEのフィルター機能(Matrix Filter)で同等のことを表現します。デモページにあるように、IEでもCSS3のtransformはおよそ実現できるみたいです(まぁ、そもそもがIEのMatrix仕様を参考に実装したのでしょうけど)。

 このスクリプトを添付しておきます。

添付ファイル: css3transform.htcattachedIcon 

 


— posted by martin at 01:02 pm   commentComment [33]  pingTrackBack [0]

 

タグモード表示の改善

category-icon

 こんばんは。コメントで、タグエントリーを総表示するときの仕様についてアドバイスがあり、確かにそうだなと思ったので。現状では、タグモードのとき(このサイトに表示されているタグのアイコンをクリックした時)、下のショットのように、縦にリスト表示されます。
shot1
数が少ないうちはよいですが・・・。

 これは、アーカイブ表示に準じてそうしたのですが数が増えてくると縦表示は見辛いですね。もっとも、スタイルシートの制御で横に並べることは出来ますが、タグクラウドの特徴のひとつである「エントリー数に応じて文字の大きさを制御する」というところまではしていませんで(PHPプログラムのmodules/tags.inc.phpの方で)。

 なので、modules/tags.inc.phpをタグクラウド表示に見合うように修正しました。適切にスタイルシートを設定すると以下のような表示になります。このショットはこのサイトでの例なのですが、タグ数が少ないのであまり雲って感じではないんですが、増えてくると見栄えも違ってくるでしょう。これよりもうちょいタグ数が多い、個人ブログの方はこんな感じLink です。
shot2
どんどん増やしていきたいなぁ。

 ちなみに、テーマ「ベーシック」での、この部分の表示は以下のようにしています。参考になれば。クラス名などは従来通りです。

/*---------------------------[ タグ 一覧表示用 ]----------------------*/
div.tags-list {
  width: 450px;
  margin: 30px auto;
  background: url(Images/clouds96.png) right top no-repeat;
}
div.tags-list ul {
  list-style: none;
  margin-top: 60px;
}
div.tags-list ul li{
  margin: 0 6px 3px 6px;
  white-space: nowrap; /* 日本語ワードの改行を適切にするための指定 */
  display: inline;
  text-align: center;
  zoom: 1;
}
div.tags-list h3 {
  margin: 2em auto;
  color: navy;
}

 これに対応したmodules/tags.inc.phpを添付しておきます。

 あ、追記ですが、この添付ファイルの最初の方に、

$minFontSize = 13;  // 最小文字サイズ(ピクセル)
$maxFontSize = 36;  // 最大文字サイズ(ピクセル)

という2行があります。これはタグ表示の文字サイズを制御するためのものです。エントリー数に応じて、タグの文字が大きくなっていきますが、際限なく大きくなっても困るので、上限を設けています。ピクセル指定です。適宜、調整して下さい。

添付ファイル: tags.inc.phpattachedIcon 

— posted by martin at 09:29 am   commentComment [2]  pingTrackBack [0]

T: Y: ALL: Online:
Created in 0.0225 sec.
prev
2017.4
next
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30