拖放。 Drag Source无法使用extjs 3.4。适用于Extjs 3.0

时间:2013-06-25 10:45:26

标签: javascript extjs drag-and-drop extjs3

我正在尝试使用extSs的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;
}

我已经使用mouseUp事件注册了函数handleTextSelection。

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?

1 个答案:

答案 0 :(得分:0)

好的,我找到了解决方案。

Extjs 3.4的ext-all-debug.js中的一些代码导致了这个问题。此代码不在3.0版本中。

要解决此问题,请在ext-all-debug.js中搜索“getLocation:function(oDD){”并注释掉以下代码。

         /*
         * The code below is to ensure that large scrolling elements will
         * only have their visible area recognized as a drop target, otherwise it 
         * can potentially erronously register as a target when the element scrolls
         * over the top of something below it.
         */
        el = Ext.get(el.parentNode);
        while (el && region) {
            if (el.isScrollable()) {
                // check whether our element is visible in the view port:
                region = region.intersect(el.getRegion());
            }
            el = el.parent();
        }

正如评论中所解释的那样,它解决了一些问题,但后来却导致了上述问题。

我不知道他们的意思

         * otherwise it 
         * can potentially erronously register as a target when the element scrolls
         * over the top of something below it. 

如果有人可以详细说明它,将会很有帮助。