首页 文章

HTML5拖放行为

提问于
浏览
13

我正在广泛使用HTML5本机拖放,它几乎完全表现自己,只有一个小例外 .

当任何东西被拖到页面上时,我正在尝试突出显示我的下拉区域 . 我最初试图通过在文档体上放置jQuery侦听器来实现这一点,如下所示:

$("body").live('dragover',function(event){lightdz(event)});
$("body").live('dragexit dragleave drop',function(event){dimdz(event)});

使用lightdz()和dimdz()更改页面上所有dropzones的背景颜色样式属性,使它们脱颖而出 . 这没用 . 每当拖动的对象进入页面上的子元素(如div容器)时,侦听器就会将其标记为dragleave事件并使dropzones变暗 .

我通过将侦听器应用于页面上的所有可见元素而不仅仅是正文来解决这个问题 . 当它跨越一个元素和另一个元素之间的边界时,它们偶尔会出现轻微的可见闪烁,但它看起来很好 .

无论如何,现在我已经改变了lightdz()和dimdz(),以便他们将快速的jQuery fadeTo()动画应用到所有非dropzones . 这在它工作时看起来很棒,并且使用户非常清楚他们可以做什么,也不能放弃 . 麻烦的是当它在元素边界之间传递时,它应用淡入淡出动画 . 这比背景颜色的偶然闪烁要明显得多,特别是因为如果对象被快速拖过多个边界,它将对动画进行排队并使页面反复淡入淡出 .

即使我不打扰fadeTo()动画,只是改变不透明度,它比背景颜色闪烁更加明显,因为整个页面改变而不仅仅是dropzone元素 .

有没有办法将整个页面作为单一元素引用以用于dragover和dragleave事件?如果失败了,有没有办法检测在浏览器窗口之外发生的丢弃?如果我跳过dragleave事件,它看起来很好,但如果任何对象被拖过浏览器窗口然后掉到它外面,整个页面都会褪色 .

3 回答

  • 1

    我真的很尴尬,这是多么容易 .

    $("*: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是一个页面范围的容器 . 如果dragleave事件将拖动的对象移到浏览器窗口之外,则event.pageX的值为0.如果它在其他任何地方发生,则它将具有非零值 .

  • 2

    我可能在这里变得过于复杂,但我会做这样的事情:

    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
        }
    });
    

    顺便说一句,这可能不会直接起作用,所以你必须稍微调整一下才能使用你的代码 .

  • 13

    我在这里尝试了接受的解决方案,但最终使用setTimeout来克服这个问题 . 我在页面范围内容器阻塞drop元素时遇到了很多麻烦,如果它在顶部浮动,并且如果它是drop元素仍然会导致问题 .

    <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>
        













    </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>

    如果您只是调用 f(); 而不是 window.setTimeout(f, 250); ,您将看到显示和隐藏元素的一些令人讨厌的闪烁 .

    http://jsfiddle.net/guYWx/

相关问题