Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
460 views
in Technique[技术] by (71.8m points)

html - Changing Mouse Cursor for HTML5 Drag Drop Files (GMail Drag Drop)

I'm trying to reproduce the way GMail handles html5 drag/drop attachments -- where as soon as you drag files over the page, it displays a new element for you to drop them on. I got that part worked out (it wasn't as straight forward as I thought it would be).

Now I'm trying to polish it up by changing the mouse cursor when the mouse is over any other element other than the drop element, to tell the user dropping isn't allowed here. I imagine I can do it with a custom cursor, but that does not appear to be what GMail is doing. The spec would suggest it's possible to change the mouse cursor as well, but I can't seem to get it working right, using dropzone/effectAllowed.

Any help would be appreciated, here's my current setup: http://jsfiddle.net/guYWx/1/

ETA: Here's what I ended up with: http://jsfiddle.net/guYWx/16/

<body style="border: 1px solid black;">
    <div id="d0" style="border: 1px solid black;">drag files onto this page</div>
    <div id="d1" style="border: 1px solid black; display: none; background-color: red;">-&gt; drop here &lt;-</div>
    <div id="d2" style="border: 1px solid black;">and stuff will happen</div>
    <div style="float: left;">mouse them all over&nbsp;</div>
    <div style="float: left;">these elements</div>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <div>end page</div>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
    var resetTimer;

    var reset = function()
    {
        $('#d1').hide();
    };

    var f = function(e)
    {
        var srcElement = e.srcElement? e.srcElement : e.target;

        if ($.inArray('Files', e.dataTransfer.types) > -1)
        {
            e.stopPropagation();
            e.preventDefault();

            e.dataTransfer.dropEffect = (srcElement.id == 'd1') ? 'copy' : 'none';

            if (e.type == "dragover")
            {
                if (resetTimer)
                {
                    clearTimeout(resetTimer);
                }
                $('#d1').show();
                console.info('dropped on <' + srcElement.tagName.toLowerCase() + ' id="' + srcElement.id + '">

e.dataTransfer.types is ' + e.dataTransfer.types + '

e.dataTransfer.files.length is ' + e.dataTransfer.files.length);

            }
            else if (e.type == "dragleave")
            {
                resetTimer = window.setTimeout(reset, 25);
            }
            else if (e.type == "drop")
            {
                reset();
                alert('dropped on <' + srcElement.tagName.toLowerCase() + ' id="' + srcElement.id + '">

e.dataTransfer.files.length is ' + (e.dataTransfer.files ? e.dataTransfer.files.length : 0));
            }
        }
    };

    document.body.addEventListener("dragleave", f, false);
    document.body.addEventListener("dragover", f, false);
    document.body.addEventListener("drop", f, false);
</script>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Did some digging through the source and found that you're supposed to set event.dataTransfer.dropEffect = 'move'; inside your dragover event handler. Googled for dropEffect to read more and found:

dataTransfer.dropEffect

Controls the feedback that the user is given during the dragenter and dragover events. When the user hovers over a target element, the browser's cursor will indicate what type of operation is going to take place (e.g. a copy, a move, etc.). The effect can take on one of the following values: none, copy, link, move.

from: http://www.html5rocks.com/en/tutorials/dnd/basics/

Edit: Here's what I ended up with: http://jsfiddle.net/guYWx/16/

Had to do one additional trick to get it working perfectly. Did this so the dropper wouldn't appear when you select text and drag it around the page:

if ($.inArray('Files', e.dataTransfer.types) > -1)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...