Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/474.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/72.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-双文件Dragover事件触发_Javascript_Jquery_Drag And Drop - Fatal编程技术网

Javascript-双文件Dragover事件触发

Javascript-双文件Dragover事件触发,javascript,jquery,drag-and-drop,Javascript,Jquery,Drag And Drop,我正在尝试创建一个文件拖放处理程序(将一个文件拖到浏览器窗口中,用于上载) 出于某种原因,当我将拖放侦听器绑定到$(“body”)而不是绑定到body中的$(“div”)时,事件会连续触发几次,有时甚至是不间断的(看似循环)。这可能是什么原因造成的 下面是代码的精简版本: var over=false; $(“正文”) .开启(“dragover”,功能(e){ e、 预防默认值(); 如果(!结束){ 过度=正确; $(“ul”)。追加($(“”)。文本(“dragover”); } }) .

我正在尝试创建一个文件拖放处理程序(将一个文件拖到浏览器窗口中,用于上载)

出于某种原因,当我将拖放侦听器绑定到
$(“body”)
而不是绑定到body中的
$(“div”)
时,事件会连续触发几次,有时甚至是不间断的(看似循环)。这可能是什么原因造成的

下面是代码的精简版本:

var over=false;
$(“正文”)
.开启(“dragover”,功能(e){
e、 预防默认值();
如果(!结束){
过度=正确;
$(“ul”)。追加($(“
  • ”)。文本(“dragover”); } }) .on(“dragleave”,函数(e){ e、 预防默认值(); 如果(超过){ 过度=错误; $(“ul”).append($(“
  • ”).text(“dragleave”); } }) .打开(“放下”,功能(e){ e、 预防默认值(); 如果(超过){ 过度=错误; $(“ul”).append($(“
  • ”).text(“drop”); } });

  • 要进行测试:将文件拖到橙色区域,您将看到事件连续多次触发。

    您正在
    主体
    HTMLElement上为
    dragover
    dragleave
    drop添加侦听器

    当您继续在DIV上拖动时,会触发一个
    dragleave
    ,因为鼠标不再在主体上拖动,而是在DIV上拖动

    其次,由于您没有停止
    DIV
    上的冒泡事件(未设置侦听器),因此在
    DIV
    上触发的dragover正在向
    主体发出嘟嘟声

    如果我恢复发言:

    鼠标进入身体(在dragover中)

    -->火焰拖过(车身)

    鼠标进入主体中的DIV

    -->火拖离(身体)

    -->火力拖过(部队)-->轰鸣事件-->火力拖过(身体)

    mouseover
    mouseout
    也存在类似的问题,可通过使用
    mouseenter
    mouseleave
    解决

    可能您可以使用
    dragenter
    事件类型尝试相同的代码。如果它不起作用,您可以检查
    事件.target
    是否是
    主体
    。此测试有助于跳过意外的拖动事件

    祝你好运

    这个名字(大部分)是正确的。简单地说:当鼠标移动到放置目标内某个元素的边缘上时,光标下的元素将获得一个
    dropenter
    ,之前光标下的元素将获得一个
    dropleave
    。这绝对适用于任何后代

    您无法检查与
    dragleave
    关联的元素,因为如果将鼠标从拖放目标移动到子元素上,您将得到子元素的
    dropenter
    ,然后是目标元素的
    dropleave
    !这有点荒谬,我不认为这是一个多么有用的设计

    这是我不久前提出的一个糟糕的基于jQuery的解决方案

    var $drop_target = $(document.body);
    var within_enter = false;
    
    $drop_target.bind('dragenter', function(evt) {
        // Default behavior is to deny a drop, so this will allow it
        evt.preventDefault();
    
        within_enter = true;
        setTimeout(function() { within_enter = false; }, 0);
    
        // This is the part that makes the drop area light up
        $(this).addClass('js-dropzone');
    });
    $drop_target.bind('dragover', function(evt) {
        // Same as above
        evt.preventDefault();
    });
    $drop_target.bind('dragleave', function(evt) {
        if (! within_enter) {
            // And this makes it un-light-up  :)
            $(this).removeClass('js-dropzone');
        }
        within_enter = false;
    });
    
    // Handle the actual drop effect
    $drop_target.bind('drop', function(evt) {
        // Be sure to reset your state down here
        $(this).removeClass('js-dropzone');
        within_enter = false;
    
        evt.preventDefault();
    
        do_whatever(evt.originalEvent.dataTransfer.files);
    });
    
    关键在于两个事实:

    • 当您将鼠标从孙辈移动到子代时,
      dragenter
      dragleave
      将按该顺序排队等待目标元素
    • dragenter
      dragleave
      一起排队
    下面是发生的情况

    • dragenter
      事件中,我设置了一些共享变量,以指示拖动运动尚未完成解析
    • 我使用延迟为零的
      setTimeout
      立即将该变量更改回原来的值
    • 但是!因为这两个事件在同一时间排队,所以在两个事件都完成解析之前,浏览器不会运行任何计划的函数。所以接下来发生的事情是
      dragleave
      的事件处理程序
    • 如果
      dragleave
      看到它与同一目标元素上的
      dragenter
      配对,这意味着鼠标必须从某个后代移动到另一个后代。否则,鼠标实际上将离开目标元素
    • 然后,
      setTimeout
      最终在零秒后解析,在另一个事件发生之前将变量设置回原位
    我想不出一个更简单的方法。

    var over=false;
    
    var over = false; 
    
    $("body")
    .on("dragover", function(e){
        e.preventDefault();
        if (! over) {
            over = true;
            $("ul").append($("<li/>").text("dragover"));    
        }
    })
    .on("dragleave", function(e){
        e.preventDefault();
        if (over) {
            over = false;
            $("ul").append($("<li/>").text("dragleave"));
        }
    })
    .on("drop", function(e){
        e.preventDefault();
        if (over) {
            over = false;
        }
    }); 
    
    $(“正文”) .开启(“dragover”,功能(e){ e、 预防默认值(); 如果(!结束){ 过度=正确; $(“ul”)。追加($(“
  • ”)。文本(“dragover”); } }) .on(“dragleave”,函数(e){ e、 预防默认值(); 如果(超过){ 过度=错误; $(“ul”).append($(“
  • ”).text(“dragleave”); } }) .打开(“放下”,功能(e){ e、 预防默认值(); 如果(超过){ 过度=错误; } });
  • 或者您可以使用
    stop()
    停止动画构建

    不理解您的示例,但可能您应该使用.stopPropagation()停止事件buble。这有时是多事件治疗的原因。。preventDefault是jquery的操作方式。stopPropagation()。preventDefault是防止事件的默认行为(如果单击链接,请使用preventDefault避免跟随链接)。停止传播停止事件的嗡嗡声。有两种不同的东西。如果您在编写的api页面中搜索“传播”一词,您将找不到任何内容。在这个脚本中,不应该发生任何事情,只需处理拖入/拖出操作。当拖到身体上方时,我想调暗屏幕并显示消息,当他们放下文件或离开屏幕时隐藏消息。不过,我相信你关于冒泡的说法是正确的。我要试试,你倒过来了
    mouseenter
    mouseleave
    是以相同方式中断的事件,而
    mouseover
    +
    mouseout
    则是您可能期望的工作方式。唉,没有
    dragout
    var over = false; 
    
    $("body")
    .on("dragover", function(e){
        e.preventDefault();
        if (! over) {
            over = true;
            $("ul").append($("<li/>").text("dragover"));    
        }
    })
    .on("dragleave", function(e){
        e.preventDefault();
        if (over) {
            over = false;
            $("ul").append($("<li/>").text("dragleave"));
        }
    })
    .on("drop", function(e){
        e.preventDefault();
        if (over) {
            over = false;
        }
    });