悬停子元素时触发HTML5 dragleave

2020/10/31 19:13 · jquery ·  · 0评论

我遇到的问题是,dragleave悬停该元素的子元素时会触发该元素事件。另外,dragenter在再次将父元素悬停时不会触发。

我做了一个简化的提琴:http : //jsfiddle.net/pimvdb/HU6Mk/1/

HTML:

<div id="drag" draggable="true">drag me</div>

<hr>

<div id="drop">
    drop here
    <p>child</p>
    parent
</div>

使用以下JavaScript:

$('#drop').bind({
                 dragenter: function() {
                     $(this).addClass('red');
                 },

                 dragleave: function() {
                     $(this).removeClass('red');
                 }
                });

$('#drag').bind({
                 dragstart: function(e) {
                     e.allowedEffect = "copy";
                     e.setData("text/plain", "test");
                 }
                });

它应该做的是div在拖曳某物时通过将其下拉为红色来通知用户这可行,但是如果您拖入p孩子,则将dragleave被发射,而div不再是红色。返回到下拉列表div也不会再次使其变为红色。有必要将其完全移出下拉菜单div,然后再次拖回下拉菜单以使其变为红色。

dragleave拖动到子元素中时是否可以防止触发?

2017年更新: TL; DR,pointer-events: none;按照下面@HD的答案中所述查找CSS ,该CSS在现代浏览器和IE11中均有效。

您只需要保留一个参考计数器,在获得Dragenter时将其递增,而在获得Dragleave时将其递减。当计数器为0时-删除类别。

var counter = 0;

$('#drop').bind({
    dragenter: function(ev) {
        ev.preventDefault(); // needed for IE
        counter++;
        $(this).addClass('red');
    },

    dragleave: function() {
        counter--;
        if (counter === 0) { 
            $(this).removeClass('red');
        }
    }
});

注意:在放置事件中,将计数器重置为零,然后清除添加的类。

你可以在这里运行

拖动到子元素中时,是否可以防止dragleave触发?

是。

#drop * {pointer-events: none;}

该CSS对于Chrome来说似乎足够了。

在Firefox中使用它时,#drop不应直接具有文本节点(否则会有一个奇怪的问题,其中一个元素“将其留给自己”),因此我建议仅将其保留一个元素(例如,在内部使用div #drop将所有内容放进去)

这是一个解决原始问题(破碎)示例的jsfiddle

我还从@Theodore Brown示例创建了简化版本,但仅基于此CSS。

不过,并非所有浏览器都实现了此CSS:http
//caniuse.com/pointer-events

看到Facebook源代码,我可以pointer-events: none;多次找到它,但是它可能与正常的降级回退一起使用。至少它是如此简单,并且可以解决很多环境下的问题。

在这里,最简单的跨浏览器解决方案(严重):

jsfiddle <-尝试在框中拖动一些文件

您可以执行以下操作:

var dropZone= document.getElementById('box');
var dropMask = document.getElementById('drop-mask');

dropZone.addEventListener('dragover', drag_over, false);
dropMask.addEventListener('dragleave', drag_leave, false);
dropMask.addEventListener('drop', drag_drop, false);

简而言之,您将在dropzone中创建一个“ mask”,继承了width和height,位置为绝对,它将在拖动开始时显示。

因此,在显示该蒙版之后,您可以通过在其上附加其他dragleave&drop事件来实现此目的。

离开或放下后,只需再次遮罩即可。

简单而没有并发症。

(提示:Greg Pettit建议-您必须确保面具遮盖了整个盒子,包括边框)

提出这个问题已经有一段时间了,并且提供了许多解决方案(包括丑陋的hack)。

我设法解决同样的问题,我在这最近已经感谢回答的答案,并认为这可能是有帮助的人谁谈到通过这个页面。整个想法是evenet.targetondrageenter每次在任何父元素或子元素上调用时in存储然后ondragleave检查当前目标(event.target)是否等于您存储在中的对象ondragenter

这两个唯一匹配的情况是拖动拖动离开浏览器窗口时。

之所以能正常工作,是因为鼠标离开一个元素(例如el1)并进入另一个元素(例如el2)时,首先el2.ondragenter调用,然后再调用el1.ondragleave只有当拖动离开/进入浏览器窗口时,event.target才会出现''el2.ondragenter 和中el1.ondragleave

这是我的工作样本。我已经在IE9 +,Chrome,Firefox和Safari上对其进行了测试。

(function() {
    var bodyEl = document.body;
    var flupDiv = document.getElementById('file-drop-area');

    flupDiv.onclick = function(event){
        console.log('HEy! some one clicked me!');
    };

    var enterTarget = null;

    document.ondragenter = function(event) {
        console.log('on drag enter: ' + event.target.id);
        enterTarget = event.target;
        event.stopPropagation();
        event.preventDefault();
        flupDiv.className = 'flup-drag-on-top';
        return false;
    };

    document.ondragleave = function(event) {
        console.log('on drag leave: currentTarget: ' + event.target.id + ', old target: ' + enterTarget.id);
        //Only if the two target are equal it means the drag has left the window
        if (enterTarget == event.target){
            event.stopPropagation();
            event.preventDefault();
            flupDiv.className = 'flup-no-drag';         
        }
    };
    document.ondrop = function(event) {
        console.log('on drop: ' + event.target.id);
        event.stopPropagation();
        event.preventDefault();
        flupDiv.className = 'flup-no-drag';
        return false;
    };
})();

这是一个简单的html页面:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Multiple File Uploader</title>
<link rel="stylesheet" href="my.css" />
</head>
<body id="bodyDiv">
    <div id="cntnr" class="flup-container">
        <div id="file-drop-area" class="flup-no-drag">blah blah</div>
    </div>
    <script src="my.js"></script>
</body>
</html>

使用正确的样式,我所做的就是每当将文件拖动到屏幕上时使内部div(#file-drop-area)更大,以便用户可以轻松地将文件放置到正确的位置。

解决此问题的“正确”方法是禁用放置目标的子元素上的指针事件(如@HD的回答)。这是我创建的jsFiddle,用于演示此技术不幸的是,这在IE11之前的Internet Explorer版本中不起作用,因为它们不支持指针事件

幸运的是,我能想出一个解决办法,其确实在旧版本的IE浏览器的工作。基本上,它涉及识别和忽略dragleave在子元素上拖动时发生的事件。因为该dragenter事件是dragleave在父节点上的事件之前在子节点上触发的,所以可以将单独的事件侦听器添加到每个子节点,从而从放置目标中添加或删除“ ignore-drag-leave”类。然后,放置目标的dragleave事件侦听器可以简单地忽略在此类存在时发生的调用。这是一个jsFiddle演示了这种解决方法它已经过测试,并且可以在Chrome,Firefox和IE8 +中运行。

更新:

我创建了一个jsFiddle,演示了使用功能检测的组合解决方案,其中使用了指针事件(如果支持的话)(当前支持Chrome,Firefox和IE11),并且如果没有指针事件支持(IE8,则浏览器会回退到向子节点添加事件) -10)。

The problem is that the dragleave event is being fired when the mouse goes in front of the child element.

I've tried various methods of checking to see if the e.target element is the same as the this element, but couldn't get any improvement.

The way I fixed this problem was a bit of a hack, but works 100%.

dragleave: function(e) {
               // Get the location on screen of the element.
               var rect = this.getBoundingClientRect();

               // Check the mouseEvent coordinates are outside of the rectangle
               if(e.x > rect.left + rect.width || e.x < rect.left
               || e.y > rect.top + rect.height || e.y < rect.top) {
                   $(this).removeClass('red');
               }
           }

if you are using HTML5, you can get the parent's clientRect:

let rect = document.getElementById("drag").getBoundingClientRect();

Then in the parent.dragleave():

dragleave(e) {
    if(e.clientY < rect.top || e.clientY >= rect.bottom || e.clientX < rect.left || e.clientX >= rect.right) {
        //real leave
    }
}

here is a jsfiddle

到目前为止,假设您的事件分别附加到每个拖动元素,那么这种对我来说仍然很有效的解决方案。

if (evt.currentTarget.contains(evt.relatedTarget)) {
  return;
}

一个非常简单的解决方案是使用pointer-eventsCSS属性只是它的值设置为none的dragstart每一个子元素。这些元素将不再触发与鼠标相关的事件,因此它们不会将鼠标捕获在其上方,因此也不会触发上的拖动拖动

auto完成拖动时,请不要忘记将此属性设置回;)

很简单的解决方案:

parent.addEventListener('dragleave', function(evt) {
    if (!parent.contains(evt.relatedTarget)) {
        // Here it is only dragleave on the parent
    }
}

一个简单的解决方案是将css规则添加pointer-events: none到子组件中,以防止触发ondragleave参见示例:

function enter(event) {
  document.querySelector('div').style.border = '1px dashed blue';
}

function leave(event) {
  document.querySelector('div').style.border = '';
}
div {
  border: 1px dashed silver;
  padding: 16px;
  margin: 8px;
}

article {
  border: 1px solid silver;
  padding: 8px;
  margin: 8px;
}

p {
  pointer-events: none;
  background: whitesmoke;
}
<article draggable="true">drag me</article>

<div ondragenter="enter(event)" ondragleave="leave(event)">
  drop here
  <p>child not triggering dragleave</p>
</div>

您可以通过jQuery源代码的一些启发在Firefox中修复它

dragleave: function(e) {
    var related = e.relatedTarget,
        inside = false;

    if (related !== this) {

        if (related) {
            inside = jQuery.contains(this, related);
        }

        if (!inside) {

            $(this).removeClass('red');
        }
    }

}

不幸的是,它在Chrome中不起作用,因为事件relatedTarget似乎不存在dragleave,并且我假设您在Chrome中工作,因为您的示例在Firefox中不起作用。 这是实现上述代码的版本

这就是Chrome的解决方案:

.bind('dragleave', function(event) {
                    var rect = this.getBoundingClientRect();
                    var getXY = function getCursorPosition(event) {
                        var x, y;

                        if (typeof event.clientX === 'undefined') {
                            // try touch screen
                            x = event.pageX + document.documentElement.scrollLeft;
                            y = event.pageY + document.documentElement.scrollTop;
                        } else {
                            x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
                            y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
                        }

                        return { x: x, y : y };
                    };

                    var e = getXY(event.originalEvent);

                    // Check the mouseEvent coordinates are outside of the rectangle
                    if (e.x > rect.left + rect.width - 1 || e.x < rect.left || e.y > rect.top + rect.height - 1 || e.y < rect.top) {
                        console.log('Drag is really out of area!');
                    }
                })

这是另一个使用document.elementFromPoint的解决方案:

 dragleave: function(event) {
   var event = event.originalEvent || event;
   var newElement = document.elementFromPoint(event.pageX, event.pageY);
   if (!this.contains(newElement)) {
     $(this).removeClass('red');
   }
}

希望这能奏效,这是一个小提琴

Not sure if this cross browser, but I tested in Chrome and it solves my problem:

I want to drag and drop a file over entire page, but my dragleave is fired when i drag over child element. My fix was to look at the x and y of mouse:

i have a div that overlays my entire page, when the page loads i hide it.

when you drag over document i show it, and when you drop on the parent it handles it, and when you leave the parent i check x and y.

$('#draganddrop-wrapper').hide();

$(document).bind('dragenter', function(event) {
    $('#draganddrop-wrapper').fadeIn(500);
    return false;
});

$("#draganddrop-wrapper").bind('dragover', function(event) {
    return false;
}).bind('dragleave', function(event) {
    if( window.event.pageX == 0 || window.event.pageY == 0 ) {
        $(this).fadeOut(500);
        return false;
    }
}).bind('drop', function(event) {
    handleDrop(event);

    $(this).fadeOut(500);
    return false;
});

我已经编写了一个名为Dragster的小程序库来处理这个确切的问题,它可以在IE之外无所事事地工作(它不支持DOM事件构造函数,但是使用jQuery的自定义事件编写类似的东西很容易),因此可以在任何地方使用

我遇到了同样的问题,并尝试使用pk7s解决方案。它可以工作,但是可以在没有任何额外dom元素的情况下做得更好。

基本上,想法是相同的-在可投放区域上添加一个额外的不可见覆盖。只允许这样做而没有任何多余的dom元素。这是CSS伪元素开始发挥作用的部分。

Java脚本

var dragOver = function (e) {
    e.preventDefault();
    this.classList.add('overlay');
};

var dragLeave = function (e) {
    this.classList.remove('overlay');
};


var dragDrop = function (e) {
    this.classList.remove('overlay');
    window.alert('Dropped');
};

var dropArea = document.getElementById('box');

dropArea.addEventListener('dragover', dragOver, false);
dropArea.addEventListener('dragleave', dragLeave, false);
dropArea.addEventListener('drop', dragDrop, false);

的CSS

之后的规则将为可放置区域创建完全覆盖的覆盖。

#box.overlay:after {
    content:'';
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    z-index: 1;
}

这是完整的解决方案:http : //jsfiddle.net/F6GDq/8/

我希望它可以帮助遇到相同问题的任何人。

只需检查拖动的元素是否为子元素(如果为子元素),就不要删除“ dragover”样式类。非常简单,对我有用:

 $yourElement.on('dragleave dragend drop', function(e) {
      if(!$yourElement.has(e.target).length){
           $yourElement.removeClass('is-dragover');
      }
  })

我偶然遇到了同样的问题,这是我的解决方案-我认为比上面的解决方案容易得多。我不确定是否是跨浏览器(可能取决于冒泡顺序)

为了简单起见,我将使用jQuery,但解决方案应独立于框架。

发生以下情况时,事件会以父级形式冒泡:

<div class="parent">Parent <span>Child</span></div>

我们附加活动

el = $('.parent')
setHover = function(){ el.addClass('hovered') }
onEnter  = function(){ setTimeout(setHover, 1) }
onLeave  = function(){ el.removeClass('hovered') } 
$('.parent').bind('dragenter', onEnter).bind('dragleave', onLeave)

就是这样。:)之所以有效,是因为即使onChild在子级上触发onEnter在父级onLeave之前触发,我们也会稍微延迟一下顺序以使其延迟,因此首先删除类,然后在毫秒后重新添加类。

我编写了一个名为滴灌的拖放模块,该模块修复了这种怪异行为。如果您正在寻找一个好的低层拖放模块,可以将其用作所有内容的基础(文件上传,应用内拖放,从外部源到外部源的拖放),则应选中此选项模块输出:

https://github.com/fresheneesz/drip-drop

This is how you would do what you're trying to do in drip-drop:

$('#drop').each(function(node) {
  dripDrop.drop(node, {
    enter: function() {
      $(node).addClass('red')  
    },
    leave: function() {
      $(node).removeClass('red')
    }
  })
})
$('#drag').each(function(node) {
  dripDrop.drag(node, {
    start: function(setData) {
      setData("text", "test") // if you're gonna do text, just do 'text' so its compatible with IE's awful and restrictive API
      return "copy"
    },
    leave: function() {
      $(node).removeClass('red')
    }
  })
})

To do this without a library, the counter technique is what I used in drip-drop, tho the highest rated answer misses important steps that will cause things to break for everything except the first drop. Here's how to do it properly:

var counter = 0;    
$('#drop').bind({
    dragenter: function(ev) {
        ev.preventDefault()
        counter++
        if(counter === 1) {
          $(this).addClass('red')
        }
    },

    dragleave: function() {
        counter--
        if (counter === 0) { 
            $(this).removeClass('red');
        }
    },
    drop: function() {
        counter = 0 // reset because a dragleave won't happen in this case
    }
});

An alternate working solution, a little simpler.

//Note: Due to a bug with Chrome the 'dragleave' event is fired when hovering the dropzone, then
//      we must check the mouse coordinates to be sure that the event was fired only when 
//      leaving the window.
//Facts:
//  - [Firefox/IE] e.originalEvent.clientX < 0 when the mouse is outside the window
//  - [Firefox/IE] e.originalEvent.clientY < 0 when the mouse is outside the window
//  - [Chrome/Opera] e.originalEvent.clientX == 0 when the mouse is outside the window
//  - [Chrome/Opera] e.originalEvent.clientY == 0 when the mouse is outside the window
//  - [Opera(12.14)] e.originalEvent.clientX and e.originalEvent.clientY never get
//                   zeroed if the mouse leaves the windows too quickly.
if (e.originalEvent.clientX <= 0 || e.originalEvent.clientY <= 0) {

花了很多小时后,我才完全按照预期工作了。我只想提供一个提示,仅当文件被拖过,文档拖过,dragleave在Chrome浏览器上引起痛苦的闪烁时。

这就是我解决问题的方法,也为用户提供了适当的提示。

$(document).on('dragstart dragenter dragover', function(event) {    
    // Only file drag-n-drops allowed, http://jsfiddle.net/guYWx/16/
    if ($.inArray('Files', event.originalEvent.dataTransfer.types) > -1) {
        // Needed to allow effectAllowed, dropEffect to take effect
        event.stopPropagation();
        // Needed to allow effectAllowed, dropEffect to take effect
        event.preventDefault();

        $('.dropzone').addClass('dropzone-hilight').show();     // Hilight the drop zone
        dropZoneVisible= true;

        // http://www.html5rocks.com/en/tutorials/dnd/basics/
        // http://api.jquery.com/category/events/event-object/
        event.originalEvent.dataTransfer.effectAllowed= 'none';
        event.originalEvent.dataTransfer.dropEffect= 'none';

         // .dropzone .message
        if($(event.target).hasClass('dropzone') || $(event.target).hasClass('message')) {
            event.originalEvent.dataTransfer.effectAllowed= 'copyMove';
            event.originalEvent.dataTransfer.dropEffect= 'move';
        } 
    }
}).on('drop dragleave dragend', function (event) {  
    dropZoneVisible= false;

    clearTimeout(dropZoneTimer);
    dropZoneTimer= setTimeout( function(){
        if( !dropZoneVisible ) {
            $('.dropzone').hide().removeClass('dropzone-hilight'); 
        }
    }, dropZoneHideDelay); // dropZoneHideDelay= 70, but anything above 50 is better
});

我有一个类似的问题-当我将鼠标悬停在子元素上,使dropzone在Google Chrome浏览器中闪烁时,我在主体的dragleave事件上隐藏dropzone的代码被连续触发。

我可以通过安排隐藏dropzone的函数而不是立即调用它来解决此问题。然后,如果触发了另一个拖动或拖动,则计划的函数调用将被取消。

body.addEventListener('dragover', function() {
    clearTimeout(body_dragleave_timeout);
    show_dropzone();
}, false);

body.addEventListener('dragleave', function() {
    clearTimeout(body_dragleave_timeout);
    body_dragleave_timeout = setTimeout(show_upload_form, 100);
}, false);

dropzone.addEventListener('dragover', function(event) {
    event.preventDefault();
    dropzone.addClass("hover");
}, false);

dropzone.addEventListener('dragleave', function(event) {
    dropzone.removeClass("hover");
}, false);

当鼠标指针离开目标容器的拖动区域时,将触发dragleave ”事件。

这很有意义,因为在许多情况下,只有父级是可丢弃的,而不是后代。我认为event.stopPropogation()应该已经处理了这种情况,但似乎无法解决问题。

上面提到的某些解决方案似乎确实适用于大多数情况,但是对于那些不支持dragenter / dragleave事件的子级(例如iframe)的子项而言,失败

一种解决方法是检查event.relatedTarget并验证它是否位于容器内,然后像我在此处所做的那样忽略dragleave事件:

function isAncestor(node, target) {
    if (node === target) return false;
    while(node.parentNode) {
        if (node.parentNode === target)
            return true;
        node=node.parentNode;
    }
    return false;
}

var container = document.getElementById("dropbox");
container.addEventListener("dragenter", function() {
    container.classList.add("dragging");
});

container.addEventListener("dragleave", function(e) {
    if (!isAncestor(e.relatedTarget, container))
        container.classList.remove("dragging");
});

你可以找到一个工作的小提琴 在这里

解决了 ..!

声明任何数组,例如:

targetCollection : any[] 

dragenter: function(e) {
    this.targetCollection.push(e.target); // For each dragEnter we are adding the target to targetCollection 
    $(this).addClass('red');
},

dragleave: function() {
    this.targetCollection.pop(); // For every dragLeave we will pop the previous target from targetCollection
    if(this.targetCollection.length == 0) // When the collection will get empty we will remove class red
    $(this).removeClass('red');
}

无需担心子元素。

即使阅读了所有这些答案,我仍然为此付出了很多努力,并认为我可以与您分享我的解决方案,因为我认为这可能是较为简单的方法之一,尽管有些不同。我的想法是完全省略dragleave事件侦听器,并在每次触发新的Dragenter事件时对dragleave行为进行编码,同时确保不会不必要地触发Dragenter事件。

在下面的示例中,我有一个表,希望通过拖放API彼此交换表行内容。在上dragenter,应将CSS类添加到您当前将其拖动到其中的行元素中,以突出显示该元素,然后在dragleave,应删除该类。

例:

基本的HTML表格:

<table>
  <tr>
    <td draggable="true" class="table-cell">Hello</td>
  </tr>
  <tr>
    <td draggable="true" clas="table-cell">There</td>
  </tr>
</table>

和dragenter事件处理功能,添加到每个表格单元格(除了dragstartdragoverdrop,和dragend处理程序,这是不具体到这个问题,所以这里没有复制):

/*##############################################################################
##                              Dragenter Handler                             ##
##############################################################################*/

// When dragging over the text node of a table cell (the text in a table cell),
// while previously being over the table cell element, the dragleave event gets
// fired, which stops the highlighting of the currently dragged cell. To avoid
// this problem and any coding around to fight it, everything has been
// programmed with the dragenter event handler only; no more dragleave needed

// For the dragenter event, e.target corresponds to the element into which the
// drag enters. This fact has been used to program the code as follows:

var previousRow = null;

function handleDragEnter(e) {
  // Assure that dragenter code is only executed when entering an element (and
  // for example not when entering a text node)
  if (e.target.nodeType === 1) {
    // Get the currently entered row
    let currentRow = this.closest('tr');
    // Check if the currently entered row is different from the row entered via
    // the last drag
    if (previousRow !== null) {
      if (currentRow !== previousRow) {
        // If so, remove the class responsible for highlighting it via CSS from
        // it
        previousRow.className = "";
      }
    }
    // Each time an HTML element is entered, add the class responsible for
    // highlighting it via CSS onto its containing row (or onto itself, if row)
    currentRow.className = "ready-for-drop";
    // To know which row has been the last one entered when this function will
    // be called again, assign the previousRow variable of the global scope onto
    // the currentRow from this function run
    previousRow = currentRow;
  }
}

代码中保留了非常基本的注释,因此该代码也适合初学者。希望这对您有所帮助!请注意,您当然需要将我上面提到的所有事件侦听器添加到每个表单元中,以使其起作用。

这是基于事件时间的另一种方法。

dragenter从子元素派发事件可由父元素捕获,并且该事件始终发生在之前dragleave这两个事件之间的时间间隔确实很短,比任何可能的人类鼠标动作都要短。因此,其想法是记住事件发生的时间,dragenter并过滤dragleave发生后“不太快”的事件。

这个简短的示例适用于Chrome和Firefox:

var node = document.getElementById('someNodeId'),
    on   = function(elem, evt, fn) { elem.addEventListener(evt, fn, false) },
    time = 0;

on(node, 'dragenter', function(e) {
    e.preventDefault();
    time = (new Date).getTime();
    // Drag start
})

on(node, 'dragleave', function(e) {
    e.preventDefault();
    if ((new Date).getTime() - time > 5) {
         // Drag end
    }
})

pimvdb ..

您为什么不尝试使用drop而不是dragleave它为我工作。希望这能解决您的问题。

请检查jsFiddle:http : //jsfiddle.net/HU6Mk/118/

$('#drop').bind({
                 dragenter: function() {
                     $(this).addClass('red');
                 },

                 drop: function() {
                     $(this).removeClass('red');
                 }
                });

$('#drag').bind({
                 dragstart: function(e) {
                     e.allowedEffect = "copy";
                     e.setData("text/plain", "test");
                 }
                });

您可以将超时与transitioning标志一起使用,并在顶部元素上侦听。 dragenter/dragleave来自子事件的事件会冒泡到达容器。

由于dragenter子元素dragleave在容器之前触发,因此我们将标志显示设置为过渡1ms ...dragleave侦听器将在1ms结束之前检查标志。

该标志仅在过渡到子元素期间为true,而在过渡到(容器的)父元素时为true

var $el = $('#drop-container'),
    transitioning = false;

$el.on('dragenter', function(e) {

  // temporarily set the transitioning flag for 1 ms
  transitioning = true;
  setTimeout(function() {
    transitioning = false;
  }, 1);

  $el.toggleClass('dragging', true);

  e.preventDefault();
  e.stopPropagation();
});

// dragleave fires immediately after dragenter, before 1ms timeout
$el.on('dragleave', function(e) {

  // check for transitioning flag to determine if were transitioning to a child element
  // if not transitioning, we are leaving the container element
  if (transitioning === false) {
    $el.toggleClass('dragging', false);
  }

  e.preventDefault();
  e.stopPropagation();
});

// to allow drop event listener to work
$el.on('dragover', function(e) {
  e.preventDefault();
  e.stopPropagation();
});

$el.on('drop', function(e) {
  alert("drop!");
});

jsfiddle:http : //jsfiddle.net/ilovett/U7mJj/

您需要删除拖动目标的所有子对象的指针事件。

function disableChildPointerEvents(targetObj) {
        var cList = parentObj.childNodes
        for (i = 0; i < cList.length; ++i) {
            try{
                cList[i].style.pointerEvents = 'none'
                if (cList[i].hasChildNodes()) disableChildPointerEvents(cList[i])
            } catch (err) {
                //
            }
        }
    }
本文地址:http://jquery.askforanswer.com/xuantingziyuansushichufahtml5-dragleave.html
文章标签: ,   ,   ,   ,  
版权声明:本文为原创文章,版权归 admin 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!