2017/08/28

HTML5とJavascriptでファイルビュアーを作ってみた。

ブラウザで

ローカルファイルを表示できるものを作ってみました。
画像とテキストファイルの取り込みができます。
いい感じ(>_<)

目次

目標

HTML+CSS+JavaScriptでローカルファイルを取り込んで表示しよう!

サンプルコード

test014.html

<!DOCTYPE html>
<html>
  <head>
    <meta content="IE=edge"
          http-equiv="X-UA-Compatible" />
    <link href="./test014css.css"
          rel="stylesheet"
          type="text/css" />
    <title>Selecters</title>
    <script type="text/javascript">

      //ファイルAPIで選択したファイルを指定のタグへ追加する関数
      //第一引数inputタグのID
      //第二引数取り込んだファイルのファイル名の表示先となるID
      //第三引数取り込んだファイルの表示先になるID
      function view(uploadfileid,filenameid,viewerid){ <====[2]
        //各オブジェクト取得
        var upfileob = document.getElementById(uploadfileid);
        var filename = document.getElementById(filenameid);
        var viewer = document.getElementById(viewerid);

        if(upfileob.files[0]!=null){
          upfileob.disabled="disabled";
          filename.innerHTML = upfileob.files[0].name;

          if(upfileob.files[0].type=="image/jpeg" ||
             upfileob.files[0].type=="image/png"){
            //FileReaderオブジェクト作成
            var filereader = new FileReader();

            //ファイルロード後のコールバック関数定義
            filereader.onload = function(e){
              viewer.innerHTML
                  += "<img class=\"photo\" src=\""
                  +  filereader.result
                  +  "\" />\n";
              upfileob.disabled="";
            }
            //ファイル読み込み
            filereader.readAsDataURL(upfileob.files[0]);
          }
          else if(upfileob.files[0].type=="text/plain"){
            //FileReaderオブジェクト作成
            var filereader = new FileReader();

            //ファイルロード後のコールバック関数定義
            filereader.onload = function(e){
              viewer.innerHTML
                  += "<div>"
                  + filereader.result;
                  + "</div>";
              upfileob.disabled="";
            }
            //ファイル読み込み
            filereader.readAsText(upfileob.files[0],"shift-jis");         
          }
          else{
            viewer.innerHTML
              += "<div>.jpeg,.png,.txt以外受付できません。</div>";

            upfileob.disabled="";
          }
        }
        else{
          filename.innerHTML = "<div>ファイルが未選択です。</div>";
        }
      }
      //view関数で処理した内容をリセットする関数
      //第一引数inputタグのID
      //第二引数取り込んだファイルのファイル名の表示先となるID
      //第三引数取り込んだファイルの表示先になるID
      function reset(uploadfileid,filenameid,viewerid){
        //各オブジェクト取得
        var upfileob = document.getElementById(uploadfileid);
        var filename = document.getElementById(filenameid);
        var viewer = document.getElementById(viewerid);

          upfileob.files[0] = null;
          filename.innerHTML = "<div>ファイルが未選択です。</div>";
          viewer.innerHTML ="";
          
      }
    </script>
  </head>
  <body>
    <div class="container">
      <main>
        <div id="myfileapi"> <====[1]
          <label id="myfilename" for="myuploadfile"></label>
          <label id="myfileapibutton" for="myuploadfile">
            ファイル選択
          </label>
          <label id="myfileapireset"
            onclick="reset('myuploadfile','myfilename','viewer');">
            リセット
          </label>
          <input type="file" id="myuploadfile"
            onchange="view('myuploadfile','myfilename','viewer');" />
        </div>
        <div>
          <button type="button"
            onclick="view('myuploadfile','myfilename','viewer');">
            ファイルを追加
          </button>
        </div>
        <div id="viewer"></div>       
      </main>
    </div>
  </body>
</html>

test014css.css

div{
  margin: 10px;
}

#myfileapibutton{
  display: table-cell;
  width: 100px;
  height: 30px;
  background-color: #FD8080;
  font-size: 15px;
  text-align: center;
  vertical-align: middle;
  border-radius: 3px;
  margin: 5px;
}
#myfileapireset{
  display: table-cell;
  width: 100px;
  height: 30px;
  background-color: #FD8080;
  font-size: 15px;
  text-align: center;
  vertical-align: middle;
  border-radius: 3px;
  margin: 5px;
}
#myfilename{
  display: table-cell;
  width: 200px;
  height: 30px;
  text-align: left;
  vertical-align: middle;
  border-radius: 3px;
  margin: 5px;
  background-color: #CCCCCC;
}
#myuploadfile{
  display: none;
}
.photo{
  width:200px;
}

実行例-表示例

ローカルから画像とテキストを選んで表示してみます。
動作に関してはChromeのほうがサックサクでした。

ポイント!

  1. <input type=file>でファイル読み込みが作成できる!
    しかし! ブラウザごとに表示が違いすぎるので、
    ファイル名の表示先、読み込みボタン,リセットボタンを自作した。(test014.htmlの[1]の部分)
    ちなみに<input type=file>を標準表示させると以下のようになる。

    IE11
    Chrome

    これ全然表示が違うんです・・・・。
  2. ファイルを読み込んだ後の処理はコールバック関数で定義する。
    ファイルの読み込み後の処理は関数をfilereader.onloadに割り当てる。
    読み込み終了後に、コールバック関数として呼び出されるが、いつ読み込みが終わらない処理をさせるので
    当然といえば当然なのかもしれない。
    今回は、画像を読んだ場合はimgタグのsrc属性に割り当てし、
    テキストだった場合にはdiv要素で包んで<div id="viewer">に動的にタグを書き足している。
    指定がない場合(filename.innerHTML = upfileob.files[0]!=null)は、
    その旨を書き足している。(test014.htmlの[2]の関数viewの処理)

終わりに

今回はファイルを取り込んで表示をするものを作りましたが、
<input type="file">はもともとファイルをpostするのに使用するものです。
今度は送り込んだ画像をサーバ側でどのようにファイルに変換するかをやってみようかと思います。
これができれば簡単な画像アップロードサイトが作れそうですね。

参考になりましたら幸いです。
ご利用は自己責任です。

以上

0 件のコメント:

コメントを投稿

AWSに手を出してフレームワークも使ってみたが・・・。

サイトを作り直しました。 AWS上に構築した Content created by AXY を作り直しました。 具体的にはbottle.pyを使ったpythonで構築したサイトからPHP7を使用したサイトに再構築しています。 特別何か問題点があったというわけで...