Drag & Drop - Rico 版

 

Ajax JavaScript Framework の Rico 1.1.2 と、 これに同梱されている Prototype 1.4.0 を使用して作成した、ドラッグ&ドロップのサンプルです。

サンプルについて、ブラウザごとの動作確認結果は Drag & Drop (Ajax JavaScript) にまとめてあります。

Demo

問題.次の表をドラッグ&ドロップにより完成させてください。

オリンピック 開催国
2004年(夏季)
アテネ
2006年(冬季)
トリノ
2008年(夏季)
ペキン
選択肢

  

ソースコード

ここでは JavaScript のみ掲載します。 CSS と HTML についてはDrag & Drop - 共通ソース(CSS, HTML) 全ソースコード を参照してください。

Rico の読み込み
<script type="text/javascript" src="/usr/lib/prototype/1.4.0/dist/prototype.js"></script>
<script type="text/javascript" src="/usr/lib/rico/1.1.2/rico.js"></script>

JavaScript
<script type="text/javascript">
//<![CDATA[
(function() {

var byClassName = document.getElementsByClassName;  // ショートカット

var correct = { opt0: 'ans1', opt1: 'ans2', opt2: 'ans0' }  // 正解

var mark = function(event) {
    var points = 0;
    var max = 0;
    for (key in correct) {
        if (! key.match(/^opt[0-2]$/)) {
            continue;   // prototype.js 1.4.0 のオブジェクト汚染を回避
        }
        var answer = $(key).parentNode.id;
        points += (correct[key] == answer) ? 1: 0;
        ++max;
    }
    var score = Math.floor(points / max * 100);
    var judge = (score >= 70) ? '合格': '不合格';
    Element.update($('result'), judge + ':' + score + '%');
}

var Dropzone = Class.create();

Dropzone.prototype = (new Rico.Dropzone()).extend({
    activate: function() { /* NOP */ },
    deactivate: function() { /* NOP */ },
    showHover: function() {
        Element.addClassName(this.htmlElement, 'dragenter');
    },
    hideHover: function() {
        Element.removeClassName(this.htmlElement, 'dragenter');
    },
    canAccept: function() {
        return byClassName('draggable', this.htmlElement).length == 0;
    }
});

var Draggable = Class.create();

Draggable.prototype = (new Rico.Draggable()).extend({
    select: function() { /* NOP */ },
    startDrag: function() {
        var draggable = this.htmlElement;
        new Rico.Effect.FadeTo(draggable, 0.5, 0, 1);   // opacity
        Element.setStyle(draggable, { 'z-index': 1 });
    },
    cancelDrag: function() {
        var draggable = this.htmlElement;
        new Rico.Effect.FadeTo(draggable, 1.0, 0, 1);
        Element.setStyle(draggable, { 'z-index': 0 });
    },
    endDrag: function() {
        var draggable = this.htmlElement;
        new Rico.Effect.FadeTo(draggable, 1.0, 0, 1);
        Element.setStyle(draggable, { 'z-index': 0 });
    }
});

window.onload = function() {
    byClassName('dropzone').each(function(dropzone) {
        dndMgr.registerDropZone(new Dropzone(dropzone));
    });
    byClassName('draggable').each(function(draggable) {
        dndMgr.registerDraggable(new Draggable('', draggable));
    });
    Event.observe($('submit'), 'click', mark, false);
    Element.setStyle($('wait'), { display: 'none' });
}

//-----------------------------------------------------------------------------
// 座標計算ロジックの差し替え(for Safari & Opera & IE)

RicoUtil.toViewportPosition = function(element) {
    var offset = Position.cumulativeOffset(element);
    offset[0] -= RicoUtil.docScrollLeft();
    offset[1] -= RicoUtil.docScrollTop();
    return { x:offset[0], y:offset[1] };
}

RicoUtil.toDocumentPosition = function(element) {
    var offset = Position.cumulativeOffset(element);
    return { x:offset[0], y:offset[1] };
}

dndMgr.setStartDragFromElement = function(e, mouseDownElement) {
    this.origPos = RicoUtil.toDocumentPosition(mouseDownElement);
    this.startx = e.clientX - this.origPos.x;
    this.starty = e.clientY - this.origPos.y;
    this.interestedInMotionEvents = this.hasSelection();
    this._terminateEvent(e);
}

dndMgr._updateDraggableLocation = function(e) {
    var draggable = this.dragElement;
    draggable.style.left = (e.clientX - this.startx) + 'px';
    draggable.style.top  = (e.clientY - this.starty) + 'px';
}

dndMgr._leftOffset = function(e) {
    return 0;
}

dndMgr._topOffset = function(e) {
    return 0;
}

//-----------------------------------------------------------------------------

}());
//]]>
</script>

更新履歴

日付 内容
2007-12-31 情報 Rico のバージョンアップ(1.1.2 → 2.0 beta 3)を見送りました。
追加 2007-02-16版(Rico 1.1.2)の、 全ソースコード ページを追加。
2007-02-16 変更 ホワイトスペースノードの削除(Element.cleanWhitespace)を止めた。 これに伴い、Dropzone#canAccept の Drop 許可ロジックを変更。
2007-02-12 変更 可読性向上のため、ソースコードを全面的に書き直し。
2006-09-19 変更 座標計算ロジックの差し替え(Opera 対応)。
2006-09-17 変更 座標計算ロジックの差し替え(IE 対応)。
追加 ドロップゾーンへの干渉をオレンジ色で表現。 ドロップゾーンに先客が居る場合は、ドロップをキャンセル。 ドラッグ中のオブジェクトを半透明化。
2006-05-19 追加 採点機能を実装。
2006-05-17 初版 ドラッグ&ドロップによる解答機能を実装