【问题标题】:HTML5 Drag & Drop : "dragleave" isn't called when "dragover" and "drop" events are listenedHTML5 拖放:在监听“dragover”和“drop”事件时不调用“dragleave”
【发布时间】:2016-02-03 12:15:39
【问题描述】:

我将 div 包含在另一个父 div 中,这两个父 div 都允许“删除”。
两种情况:

  • 案例 1:不允许放置事件:
    当我在子框中放置元素时,都执行dragleave事件,因此正确删除了两个元素的红色类,但drop没有执行

  • 案例 2:允许 Drop 事件(通过删除 js 代码中的注释):
    当我将元素放入子框中时,不会执行 dragleave 事件,并且仅在子元素上删除红色类(“drop”事件侦听器中包含的代码)

    问题:
    在情况 2 中,如果我将元素放入名为 div 的子元素中,则红色类仅在子 div 中删除,而不在父 div 中删除。在不通过event.path对象的情况下删除所有父母的班级怎么办?

    这是案例 1 的 Fiddler
    这是案例 2 的Fiddler

    var myApp = angular.module('myApp',[]);
    
     myApp.controller('MyCtrl', ['$scope', function ($scope)
                {
                }]);
    
    
    myApp.directive('drop', function() {
    return{
     	restrict: "A",
        replace: false,
    
        link: function (scope, element, attrs, ctlr) {
        	var obj = element[0];
    		var DragLeaveCounter=0;
            
            obj.addEventListener("dragenter", function (eventObject) {
                eventObject.preventDefault();
                DragLeaveCounter++;
                if (DragLeaveCounter === 1) {
                        obj.classList.add( 'red' );
                    };
               console.log("enter" , obj.id , DragLeaveCounter );
            }, false);
    
            obj.addEventListener("dragleave", function (eventObject) {
                eventObject.preventDefault();
                DragLeaveCounter--;
               if (DragLeaveCounter <= 0) {
                    obj.classList.remove('red');
               }
                console.log("leave" , obj.id , DragLeaveCounter);
            }, false);
    
    
            obj.addEventListener("drop", function (eventObject) {
                eventObject.preventDefault();
                eventObject.stopPropagation();
                console.log("drop" , obj.id , eventObject);           
                obj.classList.remove("red");
                DragLeaveCounter=0;
    
            }, false);
    
    
            obj.addEventListener("dragover", function (eventObject) {
               //TODO Remove comment in next line: 
               eventObject.preventDefault();
                console.log("dragover");
            }, false);
    
            
        }
        
    }
    });
    /* Styles go here */
    
    #parent{
        width:200px;
        height:200px;
        border:1px solid red;
        position:relative;
    }
    
    #child{
      position:absolute;
      left:50px;
      top:50px;
      width:50px;
      height:50px;
      background-color:#c7a499;
    }
    #child2{
      position:absolute;
      left:50px;
      top:110px;
      width:50px;
      height:50px;
      background-color:#c7a499;
    }
    
    .red {
        background-color: red !important;
    }
    .green {
        background-color: green;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="myApp" ng-controller="MyCtrl" >
        <i> Remove comment on line 43 in js to see what the difference (Please open the console)</i>
        <div id="drag"  draggable="true">drag me</div>
        <hr>
    
        <div id="parent" drop>
            Parent
            <div id="child" drop> 
                child
            </div>
            <div id="child2" > 
                child 2
            </div>
            
            </div>
    </div>
  • 【问题讨论】:

    • 看来问题出在那个eventObject.stopPropagation();

    标签: html drag-and-drop dom-events draggable drag


    【解决方案1】:

    drop 事件被触发时,拖放功能的正确行为是不触发dragleave 事件。如果您不在drop 事件上使用event.preventDefault(),则浏览器会尝试执行该放置操作(即:当您将链接放置在浏览器中时加载链接)。这导致leave 事件被触发。

    更多信息:https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_operations#drop

    您应该让drop 事件向上传播以在父级中收集事件,并在删除侦听器中删除eventObject.stopPropagation();

    【讨论】:

    • 是的,但是如果我删除stopPropagation,它会删除类,但它也会对所有元素执行drop操作。
    • 我在这里用另一种方式重写了这个问题:stackoverflow.com/questions/33516226/…
    猜你喜欢
    • 2020-06-19
    • 2015-12-17
    • 2011-07-28
    • 2014-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    相关资源
    最近更新 更多