Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript HTML5拖放;跌落行为_Javascript_Jquery_Html_Drag And Drop - Fatal编程技术网

Javascript HTML5拖放;跌落行为

Javascript HTML5拖放;跌落行为,javascript,jquery,html,drag-and-drop,Javascript,Jquery,Html,Drag And Drop,我正在广泛使用HTML5本机拖放功能,它几乎完全自行运行,只有一个小的例外 当任何东西被拖到页面上时,我试图突出显示我的dropzones。我最初试图通过在文档体上放置jQuery侦听器来实现这一点,如下所示: $("body").live('dragover',function(event){lightdz(event)}); $("body").live('dragexit dragleave drop',function(event){dimdz(event)}); var draggi

我正在广泛使用HTML5本机拖放功能,它几乎完全自行运行,只有一个小的例外

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

$("body").live('dragover',function(event){lightdz(event)});
$("body").live('dragexit dragleave drop',function(event){dimdz(event)});
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
    }
});
使用lightdz()和dimdz()更改页面上所有DropZone的背景色样式属性,使其突出显示。这不管用。每当拖动的对象进入页面上的子元素(如div容器)时,侦听器就会将其标记为dragleave事件,并使dropzones变暗

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

无论如何,现在我已经更改了lightdz()和dimdz(),以便它们对所有非DropZone应用一个快速的jQuery fadeTo()动画。当它工作时,它看起来很棒,并且让用户非常清楚他们可以和不能把东西放在上面。问题在于,当它在元素边界之间通过时,会应用淡入淡出动画。这比偶尔的背景色闪烁要明显得多,特别是因为如果对象被快速拖动到多个边界上,它将对动画进行排队,并使页面反复淡入淡出

即使我不用费心处理fadeTo()动画,只需更改不透明度,它也比背景颜色闪烁更为明显,因为整个页面都会更改,而不仅仅是dropzone元素


对于dragover和dragleave事件,有没有办法将整个页面作为单个元素引用?否则,是否有任何方法可以检测在浏览器窗口外发生的跌落?如果我跳过dragleave事件,它看起来很好,但是如果任何对象被拖到浏览器窗口上,然后被拖到它外面,整个页面都会褪色。

我可能会变得过于复杂,但我会这样做:

$("body").live('dragover',function(event){lightdz(event)});
$("body").live('dragexit dragleave drop',function(event){dimdz(event)});
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
    }
});
var draggingFile=false;
var事件2;
//具有类热点的元素是可以的
var热点=$(“.hostspots”);
//主体上用于拖动开始和停止的处理程序
$(“body”).live(“dragover”,函数(事件){draggingFile=true;event2=event;});
$(“body”).live(“dragexit dragleave drop”,函数(事件){draggingFile=false;event2=event;});
//函数检查文件是否被拖过OK热点,而不考虑前面的其他元素
var isTargetOK=函数(x,y){
热点。每个(功能(i、el){
el2=$(el);
var pos=el2.offset();

如果(x=>pos.left&&x pos.top&&y我真的很尴尬这一次有多容易

$("*: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。如果它发生在其他任何地方,它的值将为非零值。

我在这里尝试了可接受的解决方案,但最终使用setTimeout解决了这个问题。我在页面上遇到了很多问题-如果放置元件漂浮在顶部,则宽容器会阻塞放置元件,如果放置元件是放置元件,则仍然会导致问题

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

-到这里来-
其他元素
- 
另一个因素

















无功重置定时器; var f=函数(e) { 如果(例如类型==“dragover”) { e、 停止传播(); e、 预防默认值(); 如果(重置计时器) { clearTimeout(重置计时器); } document.getElementById('d1').style.display=''; } 其他的 { var f=函数() { document.getElementById('d1').style.display='none'; }; resetTimer=window.setTimeout(f,25); } }; 文件。正文。附录列表(“dragover”,f,true); 文件.正文.附录列表(“dragleave”,f,true); document.getElementById('d1').addEventListener(“drop”,函数(e){f();alert('drop');},false);
如果您只是调用
f();
而不是
window.setTimeout(f,250);
,您将看到显示和隐藏元素的一些令人讨厌的闪烁


http://jsfiddle.net/guYWx/

我实际上注意到fadeTo()有些问题。从拖放相关事件的完全不透明度变为部分不透明度似乎会立即发生,但从另一个方向变为完全不透明度似乎需要几秒钟的时间。这种情况发生在我的所有页面上,因此这可能与我的脚本不同,但我决定只将不透明度更改为直接的CSS更改,而不是将其设置为动画。虽然看起来不那么干净,但它确实有效,而且有点让我原来的问题变得多余。放弃这句话。我仍然在Chrome中遇到问题。Firefox无缝地处理CSS更改,但Chrome会在每次边界更改上闪烁。我会看看这样是否有效。闪烁是因为它进入时会在身体上触发一个dragleavedropzone,它使dropzone消失,再次触发dragover。我想我解决了这个问题(我的项目是八、九个月前的,所以我记不清所有细节)通过将dragover侦听器应用于页面上所有可见的块元素。您的解决方案可能更优雅。如果将事件侦听器附加到文档(而不是正文),则如果将文件拖到正文结尾下方,也会触发dragover。此解决方案不包括在当前页面上拖动元素,另请参见。至少在某些浏览器上,它是event.originalEvent.pageX,而不是event.pageX。。。