HTML5 drag & drop behaviour

前端 未结 3 1339
终归单人心
终归单人心 2021-02-13 15:12

I\'m making extensive use of the HTML5 native drag & drop, and it\'s almost entirely behaving itself, with one small exception.

I\'m trying to highlight my dropzones

相关标签:
3条回答
  • 2021-02-13 15:51

    I may be getting overly complex here but I would do something like this:

    var draggingFile = false;
    var event2;
    
    //elements with the class hotspots are OK
    var hotspots = $(".hotspots");
    
    //Handlers on the body for drag start & stop
    $("body").live("dragover", function(event){ draggingFile = true; event2 = event; });
    $("body").live("dragexit dragleave drop", function(event){ draggingFile = false; event2 = event; });
    
    //Function checks to see if file is being dragged over an OK hotspot regardless of other elements infront
    var isTargetOK = function(x, y){
        hotspots.each(function(i, el){
            el2 = $(el);
            var pos = el2.offset();
            if(x => pos.left && x <= pos.left+el2.width() && y => pos.top && y <= post.top+el2.height()){
                return true;
            }
        });
        return false;
    };
    
    //Mousemove handler on body
    $("body").mousemove(function(e){
        //if user is dragging a file
        if(draggingFile){
            //Check to see if this is an OK element with mouse X & Y
            if(isOKTarget(e.pageX, e.pageY)){
                //Light em' up!
                lightdz(event2);
            } else { /* Fade em' :( */ dimdz(event2); }
        } else {
            dimdz(); //Having no parematers means just makes sure hotspots are off
        }
    });
    

    BTW that's probably not going to work straight off the bat, so you'll have to tweak it a bit to work with your code.

    0 讨论(0)
  • 2021-02-13 16:01

    I'm genuinely embarrassed by how easy this one was.

    $("*:visible").live('dragenter dragover',function(event){lightdz(event)});
    
    $("#page").live('dragleave dragexit',function(event)
    {
        if(event.pageX == "0")
           dimdz(event);
    });
    
    $("*:visible").live('drop',function(event){dimdz(event)});
    

    #page is a page-wide container. If the dragleave event takes the dragged object outside of the browser window, event.pageX will have a value of 0. If it happens anywhere else, it'll have a non-zero value.

    0 讨论(0)
  • 2021-02-13 16:10

    I tried the accepted solution here, but ended up using setTimeout to overcome the issue. I was having a ton of trouble with the page-wide container blocking the drop element if it was floated on top, and still causing the problem if it was the drop element.

    <body style="border: 1px solid black;">
        <div id="d0" style="border: 1px solid black;">&nbsp;</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;">&nbsp;</div>
        <div style="float: left;">other element</div>
        <div style="float: left;">&nbsp;-&nbsp;</div>
        <div style="float: left;">another element</div>
        <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    </body>
    <script type="text/javascript">
        var resetTimer;
    
        var f = function(e)
        {
            if (e.type == "dragover")
            {
                e.stopPropagation();
                e.preventDefault();
                if (resetTimer)
                {
                    clearTimeout(resetTimer);
                }
                document.getElementById('d1').style.display = '';
            }
            else
            {
                var f = function()
                {
                    document.getElementById('d1').style.display = 'none';
                };
                resetTimer = window.setTimeout(f, 25);  
            }
        };
    
        document.body.addEventListener("dragover", f, true);
        document.body.addEventListener("dragleave", f, true);
        document.getElementById('d1').addEventListener("drop", function(e){ f(); alert('dropped'); }, false);
    </script>
    

    If you were to just call f(); instead of window.setTimeout(f, 250);, you'll see some nasty flickering of the element showing and hiding.

    http://jsfiddle.net/guYWx/

    0 讨论(0)
提交回复
热议问题