これでできる! クロスブラウザJavaScript入門

第22回 JavaScriptによるUIの実装:ドラッグ

この記事を読むのに必要な時間:およそ 5.5 分

汎用版ドラッグのJavaScript

function getStyle(element){
  return window.getComputedStyle ? 
    getComputedStyle(element, '') :
    element.currentStyle;
}
var IE6 = !window.XMLHttpRequest && window.ActiveXObject;
var root = document.documentElement;

var dragging = false;
var fixed = false;
var x, y, dx, dy;
var element;
addEvent(document,'mousedown', function(evt){
  if(!evt){
    evt = window.event;
  }
  var target = evt.target || evt.srcElement;
  if (target.className === 'js-drag') {
    x = evt.offsetX || evt.layerX;
    y = evt.offsetY || evt.layerY;
    dragging = true;
    element = target;
    var style = getStyle(element);
    var rect = element.getBoundingClientRect();
    var left = window.pageXOffset || root.scrollLeft;
    var top  = window.pageYOffset || root.scrollTop;
    if (style.position === 'fixed'){
      fixed = true;
      dx = 0;
      dy = 0;
    } else {
      fixed = false;
      dx = (rect.left + left) - element.offsetLeft;
      dy = (rect.top  + top ) - element.offsetTop;
    }
    if (IE6){
      element.style.removeExpression('behavior');
    }
    if (evt.preventDefault){
      evt.preventDefault();
    } else {
      evt.returnValue = false;
    }
    addEvent(document, 'mousemove', mousemove);
  }
});
addEvent(document, 'mouseup', function(evt){
  if(dragging){
    dragging = false;
    removeEvent(document, 'mousemove', mousemove);
    var rect = element.getBoundingClientRect();
    element.style.left = rect.left + 'px';
    element.style.top  = rect.top  + 'px';
    element.style.position = 'fixed';
    if (IE6) {
      element.style.position = 'absolute';
      var L = 'document.documentElement.scrollLeft';
      var T = 'document.documentElement.scrollTop';
      element.style.setExpression('behavior',
 'this.style.left=(' +(rect.left-dx)+ '+' + L + ' )+"px",'+
 'this.style.top =(' +(rect.top -dy)+ '+' + T + ' )+"px"');
     document.body.style.backgroundImage='url(about:blank)'
     document.body.style.backgroundAttachment = 'fixed';
    }
  }
});
function mousemove(evt){
  if(!evt){
    evt = window.event;
  }
  if(dragging){
    var left= fixed? 0: window.pageXOffset||root.scrollLeft
    var top = fixed? 0: window.pageYOffset||root.scrollTop
    element.style.left= left+ evt.clientX - x - dx + 'px';
    element.style.top = top + evt.clientY - y - dy + 'px';
    if (evt.preventDefault){
      evt.preventDefault();
    } else {
      evt.returnValue = false;
    }
  }
}

まとめ

今回はJavaScriptを使ったUIとしてドラッグの実装方法を紹介しました。固定配置(fixed)と非固定配置を切り替えできるようにするなど,改良できるところはまだまだあるので,是非改良を加えてみてください。

次回も引き続きJavaScriptを使ったクロスブラウザなUIの実装を見ていきたいと思います。

著者プロフィール

太田昌吾(おおたしょうご,ハンドルネーム:os0x)

1983年生まれ。JavaScriptをメインに,HTML/CSSにFlashなどのクライアントサイドを得意とするウェブエンジニア。2009年12月より、Google Chrome ExtensionsのAPI Expertとして活動を開始。

URLhttp://d.hatena.ne.jp/os0x/