こんにちは。前回に引き続き,
要素のドラッグ
ウェブアプリでよく使われるインタフェースのひとつ,
投稿フォームで入力する際,
ドラッグの基本HTML
<div class="js-drag" id="js-drag-1">
<form class="js-drag-form" onsubmit="return false;">
<textarea></textarea>
<input class="submit" type="submit" value="送信">
</form>
</div>
そして,
ドラッグの基本CSS
.js-drag{
position:absolute;
background:#555;
display:block;
margin:0;
padding:0;
border:0;
}
.js-drag form{
margin:15px;
}
.js-drag textarea{
width:400px;
height:240px;
display:block;
}
.js-drag input.submit{
width:400px;
height:30px;
}
さて,
ドラッグの基本JavaScript
var element = document.getElementById('js-drag-1');
// 要素の現在位置を取得
var rect = element.getBoundingClientRect();
// 要素をbody直下に移動
document.body.appendChild(element);
// この時,要素の位置がページ最下部に移動してしまう
var root = document.documentElement;
// 現在のスクロール量を取得
var left = window.pageXOffset || root.scrollLeft;
var top = window.pageYOffset || root.scrollTop;
// 要素の位置を戻す
element.style.left = (rect.left + left) + 'px';
element.style.top = (rect.top + top) + 'px';
var dragging = false;
element.onmousedown = function(evt){
dragging = true;
};
document.onmouseup = function(evt){
dragging = false;
};
document.onmousemove = function(evt){
if(dragging){
if(!evt){
evt = window.event;
}
var left = window.pageXOffset || root.scrollLeft;
var top = window.pageYOffset || root.scrollTop;
element.style.left = left + evt.clientX + 'px';
element.style.top = top + evt.clientY + 'px';
}
};
ドラッグの下準備として,
肝心のドラッグ処理のコードは至ってシンプルですね。マウスダウンでドラッグを開始し,
しかし,
- ドラッグを開始すると要素の位置がずれる
(要素の左上を掴んだ状態になる) - ドラッグ中にテキストを選択してしまう
- テキストエリア内の文字を選択できない
- スクロールに追従しない
(必ずしも追従したほうがよいというわけではありませんが, 今回は追従させます)
といった問題があげられます。
まず,
ドラッグ中にテキストを選択してしまう問題については,
テキストエリア内の文字を選択できない件については,
スクロールの追従については第20回で扱ったposition:fixedで実現します。