JDBな人生  専門的なことから日常的なことまで~ まぁ自由きままに書いていきます。
2017年07月 / 06月<< 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 31 >>08月

アクセスランキング

[ジャンルランキング]
コンピュータ
450位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
66位
アクセスランキングを見る>>

input type="file"の隣に画像のプレビューを表示する

input type="file"を探して勝手に画像のプレビューを表示するスクリプトです。
画像じゃなくてもプレビューを出そうとしますが、まあそれはちょこっと弄れば直せるはずです。ファイル名をチェックするとかですかね。

(function() {
  if (typeof FileReader == "undefined") return;
  document.addEventListener("DOMContentLoaded", function() {
    var images = [];
    Array.prototype.forEach.apply(
      document.getElementsByTagName("input"), [
        function(input, index) {
          if (input.type != "file") return;
          var image = document.createElement("img");
          image.width = 150;
          input.parentNode.insertBefore(
            image,
            input.nextSibling
          );
          images[index] = image;
          input.addEventListener("change", function() {
            if (!input.files[0]) return;
            var reader = new FileReader();
            reader.addEventListener(
              "load",
              function() {
                images[index].src = this.result;
              },
              false
            );
            reader.readAsDataURL(input.files[0]);
          }, false);
        }
      ]
    );
  }, false);
})();

割と使い所がありそうなのであげておきました。参考までに。
   JavaScript    TB(0)    CM(0)    EDIT    ページ↑

xSVをテーブルにする

近頃は(というほど近くもないですが)、JavaScriptのArrayも色々と拡張されて、forEach()やらmap()やらが使えるようになっています。例えばTSVをTableにするようなスクリプトもこんな感じですっきりと書けます。

var tsv2Table = function(tsv, table) {
  tsv
    .split(/\r\n|\r|\n/)
    .map(
      function(row) {
        return row.split('\t');
      })
    .forEach(function(cols) {
      var tr = table.appendChild(
        document.createElement('tr')
      );
      cols.forEach(function(col) {
        tr.appendChild(
          document.createElement('td')
        ).appendChild(
          document.createTextNode(col)
        );
      });
    });
}

少し変えればCSVや他のxSVにも対応できます。
といっても、もはやこの程度ならググって持ってくるよりも自分で書いたほうがはやいかもしれません。

forEachもmapも一部の古いブラウザでは対応していませんが、CSSや他のAPIの対応状況を考えればどのみち切り捨てざるを得ないので、そんなに気にしなくて良い感じもします。それでももし使いたければ、MDNに互換のコードがあるのでそれをコピペすれば大丈夫です。

Array.prototype.forEach() - JavaScript | MDN
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

#こういうコードってこうやって載せるよりGitHubとかにあげたほうがいいのかな…
   JavaScript    TB(0)    CM(0)    EDIT    ページ↑

スワイプ操作のスライド機能、DDScrollHandler

先日、ドラッグ&ドロップ操作を実現するためのライブラリDDHandlerを公開しましたが、そのコードを少し改造して、左右にスワイプ(フリック)をすることで操作ができるスライドのコンポーネント、DDScrollHandlerを作ってみました。

JS
jdbtools_DDScrollHandler.js

CSS
jdbtools_autoScrollComponent.css

ドラッグしている間はマウス操作に沿って動かし、離した瞬間に、元のページに戻るか、次のページに移るかを判定する、という仕組みで動いています。

GPUアクセラレーションなどもあるので、環境により、transition & transform , transition & left, setInterval & left の3パターンでアニメーションを行います。
基本的にCSSアニメーションで動くので他のJSで動かすライブラリよりは滑らかになるはず…

使い方

var handler = new DDScrollHandler();
handler.setAreaSize(要素の横幅[px], 要素の縦幅[px]);
handler.setScrollTarget(リストの親要素[element], リストの種類[String]);



使い道としては、チュートリアルやヘルプなど、利用者が気軽に読めると良いドキュメント等で使うと良さそうです。
実際に使う場合はページ数表示があったほうがよさそう。ちなみにそのためのsetOnPageChangedListenerというイベントも用意してあります。

まあいろいろと考えていこうと思います。
   JavaScript    TB(0)    CM(0)    EDIT    ページ↑

CKEditorにCtrl + Sのショートカットキーを実装する

最近、テキストエディタとして、CKEditorというライブラリを導入しました。主要な機能を網羅しており、バージョンを選べばIE7にも対応しているという、なかなかの優れものです。
このCKEditorにはキーボードのコマンドを登録する機能があるので、ショートカットキーの動作を簡単にオーバーライドすることができます。Keyboardイベントを自力で書くのよりも楽です。

以下よりどうぞ。
   JavaScript    TB(0)    CM(0)    EDIT    ページ↑

【改訂版】JSでドラッグ&ドロップを実装する(スマホ対応)

最近、久々にWEB関連の開発を少々やっています。今日は主にクライアントサイドのコーディングをしました。
さて、3年近く前に、DOM要素のドラッグ&ドロップのコードを紹介しましたが、わかりにくく、スマホにも対応していなかったので、書きなおしてみました。

参考:
要素のドラッグ(IE,FF,GC対応) - JDBな人生
http://jabnz.blog69.fc2.com/blog-entry-735.html

今回は、「初期化」「移動量の取得」「設定値の計算」「代入」等の処理を、それぞれはっきりと分けて書いてみました。
また、オブジェクト型を使ったクラス実装も使っています。

var DDHandler = (function(){
    var that = {};
    
    /* イベント情報からマウスポインタの座標を取得 */
    var getMousePosition = function(e){
        // 座標値取得のクロスブラウザ対応
        if (e) return [e.pageX, e.pageY];
            else if(window.event) return [event.clientX, event.clientY];
    }
    
    /* スタイル値(文字列)から数値を取得 */
    var getPixelValue = function(str){
        if (str && str.match(/^\d{1,}(\.\d{1,})*px$/)) return Number(str.replace(/px/g, ""));
            else return 0;
    }
    
    /* オブジェクトを引数の値分移動する */
    var moveElement = function(target, dx, dy){
        var obj = {}, l, r, t, b;
        if (document.defaultView && document.defaultView.getComputedStyle){
            obj = document.defaultView.getComputedStyle(target, "");
        } else if (target.currentStyle) {
            obj = target.currentStyle;
        }
        l = obj.left, r = obj.right, t = obj.top, b = obj.bottom;
        
        if (l + "" == "auto") target.style.right = (getPixelValue(r) - dx) + "px";
            else target.style.left = (getPixelValue(l) + dx) + "px";
        if (t + "" == "auto") target.style.bottom = (getPixelValue(b) - dy) + "px";
            else target.style.top = (getPixelValue(t) + dy) + "px";
    }
    
    /* オブジェクトへのハンドラの設定 */
    var setDragAndDropListener = function(target, handle){
        if (typeof target.draggable != "undefined") target.draggable = false; // ブラウザ実装のドラッグを禁止
        if (typeof target.unselectable != "undefined") target.unselectable = true; // 選択禁止
        if (typeof handle == "undefined") handle = target; // 掴む部分を指定していない場合全体とする
        
        var type = null;
        var regExp = null;
        var op = [];
        var start = function(e){
            if (type != null) return;
            if (e && e.type.match(/touch/g))
                type = "touch";
            else
                type = "mouse";
            if (e && e.targetTouches) e = e.targetTouches[0];
            regExp = new RegExp(type, "g");
            op = getMousePosition(e);
        }
        
        var move = function(e){
            if (!type) return;
            if (e && !e.type.match(regExp)) return;
            if (e && e.targetTouches) e = e.targetTouches[0];
            var np = getMousePosition(e);
            var dx = np[0] - op[0], dy = np[1] - op[1];
            moveElement(target, dx, dy);
            op = np;
        }
        var end = function(e){
            if (!type) return;
            if (e && !e.type.match(regExp)) return;
            if (e && e.targetTouches) e = e.targetTouches[0];
            var np = getMousePosition(e);
            var dx = np[0] - op[0], dy = np[1] - op[1];
            moveElement(target, dx, dy);
            type = null;
        }
        
        if (document.addEventListener) {
            document.addEventListener("mouseup", end, false);
            document.addEventListener("touchmove", function(event){
                if (type == "touch") event.preventDefault();
                return false;
            }, false);
        } else {
            document.attachEvent("onmouseup", end)
        }
        
        // addEventListenerはイベントの伝播の処理が面倒なのでここでは直接代入
        handle.onmousedown = start;
        handle.onmousemove = move;
        handle.onmouseup = end;
        
        handle.ontouchstart = start;
        handle.ontouchmove = move;
        handle.ontouchend = end;
        
        /* 選択処理への対策 */
        handle.onselectstart = function() {
            return false;
        }
    }
    that.setDragAndDropListener = setDragAndDropListener;
    
    return that;
})();



使用法は、display: absolute;(fixed)な要素のインスタンスを取得して、DDHandlersetDragAndDropListener(対象オブジェクト);と実行するのみです。
サンプルもおいておきます。

要素ドラッグサンプル
141230.html


可読性や構造の簡潔さはだいぶ向上しているように思えます。(やっていることは同じですが)

過去に書いたコードと、現在書けるコードを見比べてみるのもなかなか面白いですね。
   JavaScript    TB(0)    CM(0)    EDIT    ページ↑

プロフィール

JDB Luigi

Author:JDB Luigi
どこにでもいるようなありふれた人間・・・という訳でもなく、かと言って怪しい宗教を信仰する変人という訳でも無い。

基本的に掲載しているコード等は煮ていただいても焼いていただいても結構ですが、利用は自己責任にてお願いいします。
また、バグ・アドバイス等もしあればよろしくお願いします。