简体   繁体   中英

HTML5 Drag and drop issues

I have set up drag and drop on a list of items so that the user can drag and drop an item into a preview pane and see its content. As expected the cursor changes to the expected "ghost" image and everything works as expected.

Previously, in the same application, I created custom scrollbars that work by nesting mousemove and mouseup within a mousedown on the scrollbar. As the mouse moves the page scrolls. This still works as expected.

However after scrolling, the preview system's drag and drop cursor is messed up: it no longer changes to the expected cursor(s) & attached ghost image.

I suspect that the act of scrolling (dragging the "scrubber" up and down the scrollbar's "track" is somehow triggering the html5 d&d system. I have tried putting e.preventDefault pretty much everywhere in the scrollbar to no effect.

I'm guessing that somehow the html5 d&d needs to be disabled while scrolling, or fooled into thinking that the scrollbar, while not a real drag and drop, has actually completed or reset whatever flags, or fulfilled whatever expectations, the d&d system has for a completed operation.

As a test I used the html5 d&d for the scrollbar (but due to the cursor changes on dragging just looks weird) and as expected the item preview d&d works correctly with all the expected cursor behaviors.

Any suggestions on how to reset so that the d&d cursor shows correctly would be much appreciated.

The code is in an Edge Animate framework, here are the key fragments:

//scrollbar code

Symbol.bindElementAction(compId, symbolName, "${scrubber}", "mouseenter", function(sym, e) {
    sym.$("scrubber").attr("draggable", "false");
    return false; ///
});

Symbol.bindElementAction(compId, symbolName, "${scrubber}", "mousedown", function(sym, e) {
    e.preventDefault();
    e.stopPropagation();
    var scrubber = sym.$("scrubber");
    var mouseButton = e.button;
    if(mouseButton == 2){
        return false;
    }
    var doMoveAtEnd = false;
    canDrag = true;
    sym.$("Hithilite").show();
    var barProp = voodoo.scrollbarCalc("", "vertical", "verticalscroll.scrubber.init");

    getStage().getSymbol("Domtop").$("Domtopreduced").mousemove(function(e){
        e.preventDefault();
        e.stopPropagation();
        if(mouseButton !== 2 && canDrag){
            isDrag = true;
            var pos = 0;
            var currOffsetY = scrubber.offset().top;
            var possibleY = e.pageY;
            if(possibleY > currOffsetY){
                scrollDir = "up";
            }
            else if(possibleY < currOffsetY){
                scrollDir = "down";
            }
            pos = pos + possibleY;
            if(pos !== 0){
                scrollProp = voodoo.scrollbarCalc(e, "vertical", "verticalscroll.scrubber.2");
                voodoo.viewScroll(e, "mousedrag", scrollDir, scrollProp[7]);
            }
            pos = 0;
            }
        }
        return false;
    });
    getStage().getSymbol("Domtop").$("Domtopreduced").mouseup(function(e){
        e.preventDefault();
        e.stopPropagation();
        var mouseButton = e.button;
        if(mouseButton !== 2){
            isDrag = false;
            canDrag = false;
            setVar("scrubber", "");
        }
        return false;
    });
    return false;
});
//Preview drag & drop
//drag source
sym.$("hotspotfocus").attr("draggable", "true");

Symbol.bindElementAction(compId, symbolName, "${hotspotfocus}", "dragstart", function(sym, e) {
    if(getVar("hardpreview") == "off"){
        return false;
    }
    setVar("dragDropItem", e.target.id);
    setVar("isDrag", true);
});
//drag target
Symbol.bindElementAction(compId, symbolName, "${hpvslot1}", "dragover", function(sym, e) {
    e.preventDefault();
    e.stopPropagation();
    if(getVar("hpvslot1") === ""){
        sym.$("hpvslot1BG").fadeTo(0, 0.5);
    }
    else{
        sym.$("hpvslot1BG").show();
    }
    return false; ///
});

Symbol.bindElementAction(compId, symbolName, "${hpvslot1}", "drop", function(sym, e) {
    e.preventDefault();
    e.stopPropagation();
    sym.$("hpvslot1BG").fadeTo(0, 1);
    voodoo.hpvDrop("hpvslot1");
    return false; ///
});


Symbol.bindElementAction(compId, symbolName, "${hpvslot1}", "dragleave", function(sym, e) {
    e.stopPropagation();
    e.preventDefault();
    if(getVar("hpvslot1") !== ""){
        sym.$("hpvslot1BG").hide();
    }
    else{
        sym.$("hpvslot1BG").fadeTo(0, 1);
    }
});

Symbol.bindElementAction(compId, symbolName, "${hpvslot1}", "dragend", function(sym, e) {
    e.preventDefault();
    sym.$("hpvslot1BG").hide();
});

Stumbled on the answer by accident.

It turns out that once the scrollbar's mousemove is activated by the scrubber (ie the first time you scroll by dragging) the scrollbar's mousemove function remains activated and scrolling anywhere in the view triggers mousemove.

This unintentional triggering is defeating the correct cursor response in the html5 drag&drop.

By stopping propagation at a lower level this is prevented (the event is being triggered in the scrollbar even though the mouse button is not "down" on the scrubber).

Unexpected!

In essence the issue here is that even though the offending mousemove handler is nested in a situation where you wouldn't think it would be fired unless the enclosing mousedown is triggered, it is, after being triggered for the first time, always triggered, regardless of whether the mouse is down or not.

The answer is have only one mousemove handler connected to the element...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM