<script type="text/javascript">
//<![CDATA[
(function() {
//-----------------------------------------------------------------------------
// ドラッグ&ドロップの制御
var dnd = {}
dnd.dropzone = []; // ドロップゾーン(ユーザアプリケーションで指定:1/2)
dnd.elmDrag; // ドラッグ中の要素
dnd.offsetX; // ドラッグ要素とマウスカーソルの位置関係 X
dnd.offsetY; // ドラッグ要素とマウスカーソルの位置関係 Y
// ドラッグ開始
dnd.onDragBegin = function(event) {
dnd.elmDrag = event.currentTarget;
var scrpos = dom.getScrollPosition();
var clipos = dom.getClientPosition(dnd.elmDrag);
dnd.elmDrag.style.position = 'absolute'; // 絶対座標へ移行
dnd.elmDrag.style.left = (scrpos.left + clipos.left) + 'px';
dnd.elmDrag.style.top = (scrpos.top + clipos.top) + 'px';
dnd.elmDrag.style.opacity = 0.5;
dnd.elmDrag.style.zIndex = 1;
dnd.offsetX = event.clientX - clipos.left;
dnd.offsetY = event.clientY - clipos.top;
document.addEventListener('mousemove', dnd.onDragMove, false);
document.addEventListener('mouseup', dnd.onDragEnd, false);
event.preventDefault();
}
// ドラッグ要素の表示位置を移動
dnd.onDragMove = function(event) {
var scrpos = dom.getScrollPosition();
dnd.elmDrag.style.left = (scrpos.left + event.clientX - dnd.offsetX) + 'px';
dnd.elmDrag.style.top = (scrpos.top + event.clientY - dnd.offsetY) + 'px';
dnd.getAcceptable(event);
event.preventDefault();
}
// ドラッグ終了
dnd.onDragEnd = function(event) {
dnd.elmDrag.style.position = 'static'; // 通常座標へ戻る
dnd.elmDrag.style.left = '0px';
dnd.elmDrag.style.top = '0px';
dnd.elmDrag.style.opacity = 1.0;
dnd.elmDrag.style.zIndex = 0;
var elmDrop = dnd.getAcceptable(event);
if (elmDrop) {
dnd.onDragDrop(elmDrop, dnd.elmDrag);
}
document.removeEventListener('mousemove', dnd.onDragMove, false);
document.removeEventListener('mouseup', dnd.onDragEnd, false);
event.preventDefault();
}
// ドロップされたときの処理
dnd.onDragDrop = function(dropzone, draggable) {
// (ユーザアプリケーションで指定:2/2)
}
// ドロップ受け入れ可能状態の要素を取得
dnd.getAcceptable = function(event) {
for (idx in dnd.dropzone) {
var elm = dnd.dropzone[idx];
if (dom.inBounds(elm, event)) {
elm.style.backgroundColor = 'orange';
return elm;
}
else {
elm.style.backgroundColor = 'white';
}
}
return null;
}
//-----------------------------------------------------------------------------
// DOM ユーティリティ
var dom = {}
// ブラウザのスクロール量を取得
dom.getScrollPosition = function() {
return {
left: document.body.scrollLeft || document.documentElement.scrollLeft,
top: document.body.scrollTop || document.documentElement.scrollTop
}
}
// 要素のクライアント座標を取得
dom.getClientPosition = function(elm) {
if (/*@cc_on!@*/false) { // IE
return {
left: elm.getBoundingClientRect().left - 2,
top: elm.getBoundingClientRect().top - 2
}
}
var result = { left: 0, top: 0 }
if (!window.netscape && !window.opera && window.devicePixelRatio) { // Safari
result.left -= elm.clientLeft;
result.top -= elm.clientTop;
while (elm) {
result.left += elm.offsetLeft + elm.clientLeft;
result.top += elm.offsetTop + elm.clientTop;
elm = elm.offsetParent;
}
}
else { // Firefox, Opera, Others...
while (elm) {
result.left += elm.offsetLeft;
result.top += elm.offsetTop;
elm = elm.offsetParent;
}
}
var scrpos = dom.getScrollPosition();
result.left -= scrpos.left;
result.top -= scrpos.top;
return result;
}
// 要素がクライアント座標上に占める領域を取得
dom.getClientBounds = function(elm) {
var clipos = dom.getClientPosition(elm);
return {
left: clipos.left,
top: clipos.top,
right: clipos.left + elm.offsetWidth - 1,
bottom: clipos.top + elm.offsetHeight - 1
}
}
// 要素の上にマウスカーソルが進入しているか?
dom.inBounds = function(elm, event) {
var bounds = dom.getClientBounds(elm);
if (event.clientX > bounds.left &&
event.clientX < bounds.right &&
event.clientY > bounds.top &&
event.clientY < bounds.bottom) {
return true; // 進入している!
}
return false;
}
// クラス名で指定された要素を取得
dom.getElementsByClassName = function(name, node) {
var result = [];
var children = (node || document).getElementsByTagName('*');
for (var idx = 0; idx < children.length; ++idx) {
if (children[idx].className.match(new RegExp(name))) {
result.push(children[idx]);
}
}
return result;
}
//-----------------------------------------------------------------------------
// ユーザアプリケーション
var correct = { opt0: 'ans1', opt1: 'ans2', opt2: 'ans0' } // 正解
// 採点
var mark = function(event) {
var points = 0;
var max = 0;
for (key in correct) {
var answer = document.getElementById(key).parentNode.id;
points += (correct[key] == answer) ? 1: 0;
++max;
}
var score = Math.floor(points / max * 100);
var judge = (score >= 70) ? '合格': '不合格';
document.getElementById('result').innerHTML = judge + ':' + score + '%';
}
// ドロップされたときの処理
dnd.onDragDrop = function(dropzone, draggable) {
if (dom.getElementsByClassName('draggable', dropzone).length == 0) {
dropzone.appendChild(draggable);
}
}
// 初期化
window.addEventListener('load', function() {
dnd.dropzone = dom.getElementsByClassName('dropzone');
var draggable = dom.getElementsByClassName('draggable');
for (idx in draggable) {
draggable[idx].addEventListener('mousedown', dnd.onDragBegin, false);
}
document.getElementById('submit').addEventListener('click', mark, false);
document.getElementById('wait').style.display = 'none';
}, false);
}());
//]]>
</script>
|