[Javascript]「JavaScript/Flash/HTML 5 でスパゲッティコードにならないためのモダン設計入門」写経 第2弾

「JavaScript/Flash/HTML 5 でスパゲッティコードにならないためのモダン設計入門」写経 - @ikikko のはてなダイアリーに引き続き。今日は第4章をやってみました。今回も、仕様だけを頭に入れて、極力本誌を見ずに実装。

この章で身に付けたいものは、二つ。

  • リッチなUIの実装方法(ドラッグ&ドロップ可能なコンポーネント
  • 状態管理の考え方

で、結論から言うと、かなり中途半端。いったんはナイーブな方法で実装してその次に状態管理を考えたものを作ろうとして、一応できた。けどちょっとイレギュラーなことをやるとすぐにバグるし、状態管理の方は途中で集中力が切れたんで未完成…><

もう考えるのもめんどくなってきたので、ナイーブな実装方法だけでもとりあえず晒しておきます。。。

WEB+DB PRESS Vol.53

WEB+DB PRESS Vol.53

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Web+DB Vol.53 State</title>
<link rel="stylesheet" type="text/css" href="./mvc-state.css" />
<script src="http://www.google.com/jsapi"></script>
<script>google.load("jquery", "1");</script>
<script src="mvc-state-naive.js"></script>
<!-- <script src="mvc-state.js"></script> -->
</head>
<body onselectstart="return false;"
      onmousedown="if (typeof event.preventDefault != 'undefined') { event.preventDefault(); }">

<ul id="list">
    <li>Item-1</li>
    <li>Item-2</li>
    <li>Item-3</li>
    <li>Item-4</li>
    <li>Item-5</li>
</ul>

<span id="drag-item">test</span>

</body>
</html>
#list li {
    cursor: pointer;
    font-size: 20px;
}

#drag-item {
    display: none;
    background: yellow;
    alpha: 0.5;
    z-index: 99;
    position: absolute;
    font-size: 20px;
}

.drag-over {
    border-bottom: 2px dashed #777;
    background: #FED;
}
$(function() {
	var isMousedown = false;
	var selectItem;

	// --------------- Helper function --------------------- //
	function onDrag(event) {
		selectItem = $(event.target).css("border", "dotted");
		isMousedown = true;
	}

	function offDrag() {
		selectItem.css("border", "none");
		isMousedown = false;
	}

	function displayDragItem(event) {
		$("#drag-item").css( {
			"display" : "inherit",
			"top" : event.pageY + 10,
			"left" : event.pageX + 10
		}).text(selectItem.text());
	}

	function noDisplayDragItem() {
		$("#drag-item").css("display", "none");
	}

	function overItem(event) {
		$(event.target).addClass("drag-over");
	}

	function noOverItem(event) {
		$(event.target).removeClass("drag-over");
	}

	// --------------- Event function --------------------- //
	// マウスを押したとき
	$("#list li").mousedown(function(event) {
		onDrag(event);
		displayDragItem(event);
	});

	// マウスカーソルが重なったとき
	$("#list li").mousemove(function(event) {
		if (isMousedown) {
			displayDragItem(event);
			overItem(event);
		}
	});

	// マウスカーソルが離れたとき
	$("#list li").mouseout(function(event) {
		if (isMousedown) {
			noOverItem(event);
		}
	});

	// マウスを離したとき
	$("#list li").mouseup(function(event) {
		offDrag();
		noDisplayDragItem();
		noOverItem(event);

		$(event.target).after(selectItem);
	});
});