素人がプログラミングを勉強していたブログ

プログラミング、セキュリティ、英語、Webなどのブログ since 2008

連絡先: すかいぷ:javascripter_  か javascripter あっと tsukkun.net skypeのほうがいいです

Grab and Drag for Google Chrome

MacのChromiumの最新版でしか確認していないのでそれ以外の環境で動くかは未確認。それから、cursor: -webkit-grab等の値は認識されているがカーソルに反映されていないようであり、よくわからないのでそのままにしてある。
乗り遅れないうちに、Google Chromeの拡張でも書いておこうかなと思って、Google Chromeで使えるGrab and Drag(iPhoneやAdobeReaderみたいに掴んでスクロールできる物)を作った。
javascripter/Grab-and-Drag · GitHub
grab_and_drag.crx
現状ではメインの部分は下のようになっていて、クリックしてから300ms以上マウスを動かさなかったらドラッグではなくテキストの選択ができるようにした。
こういった状態遷移のあるプログラムでは、Stateパターンを使うとif文による判定を減らすことができて、コードが見やすくなる。

var data;
var orig = {
  mousedown: function () {},
  mousemove: function () {},
  mouseup: function () {}
};
 
var waiting = Object.create(orig);
waiting.name = "waiting";
waiting.mousedown = function (e) {
  data = e;
  trans(judging);
};
 
var selecting = Object.create(orig);
selecting.name = "selecting";
selecting.mouseup = function (e) {
  trans(waiting);
};
 
var judging = Object.create(orig);
judging.mousemove = function (e) {
  if ((e.timeStamp - data.timeStamp) > 300) {
    trans(selecting);
  } else {
    trans(grabbing);
  }
};
 
var grabbing = Object.create(orig);
grabbing.name = "grabbing";
grabbing.mousemove = function (e) {
  window.scrollBy(data.clientX - e.clientX, data.clientY - e.clientY);
  data = e;
};
grabbing.mouseup = function () {
  trans(waiting);
};
 
var state;
 
var trans = function (next) {
  state = next;
  document.documentElement.setAttribute("data-grab_and_drag", state.name);
};
 
trans(waiting);
 
var handle = function (type) {
  document.documentElement.addEventListener(type ,function (e) {
    state[type](e);
  }, false);
};
 
handle("mousedown");
handle("mousemove");
handle("mouseup");