2

ExtjsのdragSourceでドラッグアンドドロップを実現しようとしています。ユーザーはテキストを選択し、ドロップ ゾーンにドラッグ アンド ドロップできる必要があります。ユーザーがテキストを選択すると、ドラッグ ソース インスタンスが作成されます。

このコードは、Extjs バージョン 3.0 で正常に動作しています。現在、次の問題を引き起こしているバージョン 3.4 に移行しました。

ウィンドウを下にスクロールして、最初は表示されていなかったテキストを選択すると、ドラッグできません。テキストは適切に選択され、適切なスタイルが適用されますが、ドラッグできません。問題は、テキストを下にスクロールする必要がある場合です。

以下は、ドラッグ ソースを作成するコードです。

handleTextSelection:function() {
    var range = this.getRangeObject();
    if (range) {
        if ( (range.text && range.text.length == 0) || (range.toString && range.toString().length == 0)) {
            this.lastUserSelection = null;
            return;
        }
        var node = document.createElement("div");
        node.id = "user_selection_" + SEM.util.getUID();
        node.className = "anno_user_selection";
        if (range.surroundContents) {
            range.surroundContents(node);
        } 
        node.style.display = "inline";
        var el = Ext.get(node.id);
        this.lastUserSelection = el;
        if (el) {
            el.dragSource = new Ext.dd.DragSource(el);
            el.dragSource.dragData = {
                objectType:SEM.JSGraph.USER_SELECTION_TYPE,
                nodes:[node],
                text:el.dom.textContent.trim(),
                title:el.dom.textContent.trim()
            };
        }
    }else if (!SEM.JSGraph.currentEditor.selectionstate){
        if (this.lastUserSelection) {
            var el = this.lastUserSelection;
            Ext.DomHelper.insertAfter(el.dom.previousSibling, el.dom.textContent);
            el.dom.parentNode.removeChild(el.dom);
            //Ext.DomHelper.overwrite(el, el.dom.textContent);
        }
        this.lastUserSelection = null;          
    }       

以下は、範囲オブジェクトを作成するために使用される getRangeObject 関数です。

getRangeObject:function() {
    var selection = null;
    if (window.getSelection) {
        selection = window.getSelection();
    }else if (document.getSelection) {
        selection = document.getSelection();
    }else if (document.selection) {
        selection = document.selection.createRange();
    }
    var range = null;
    if (selection != "") {
        if (selection.getRangeAt) {
            range = selection.getRangeAt(0);
        }else if(document.createRange) {
            range = document.createRange();
            range.setStart(selection.anchorNode, selection.anchorOffset);
            range.setEnd(selection.focusNode, selection.focusOffset);
        } else {
            range = selection;
        }
    }
    return range;
}

関数 handleTextSelection を mouseUp イベントに登録しました。

Ext.getBody().on("mouseup",this.handleTextSelection.createDelegate(this));

このコードは Extjs 3.0 で完全に動作します。しかし、Extjs 3.4 で使用すると、上記の問題に直面します。

デバッグ中に次の事実が見つかりました。これは役立つ場合があります。

1: ドラッグ元の以下のイベントにリスナーを登録しました。

el.dragSource.startDrag = function(){
    alert('startDrag');
};
el.dragSource.b4Drag = function(){
    alert('b4Drag');
};
el.dragSource.onBeforeDrag = function(){
    alert('onBeforeDrag');
};
el.dragSource.onStartDrag = function(){
    alert('onStartDrag');
};

予想どおり、これらのイベントは最初に表示されるテキストに対して発生します。ただし、最初は表示されないテキストについては、onBeforeDrag イベントのみが発生します。

2: fireFox と chrome の動作は同じです。したがって、これはブラウザ固有の問題ではないようです。

上記のコードで Extjs 3.4 仕様に関して何か問題はありますか? この問題が Extjs 3.4 で直面する理由を指摘できる人はいますか?

4

1 に答える 1