【问题标题】:HTML5 native DragEnter/DragLeave Events keep firing alternativelyHTML5 原生 DragEnter/DragLeave 事件交替触发
【发布时间】:2015-05-03 09:30:44
【问题描述】:

我在我的 Angular 应用程序中使用原生 HTML 拖放,发现此事件闪烁问题

This 回答不能解决我的问题,因为他们正在手动移动元素。我将其留在本机实现上。

我的简化代码:

var app = angular.module('app', []);
app.directive('amDnd', function() {
  return {
    scope: true,
    link: function($scope, $element, $attr) {
      var el = $element[0];
      el.draggable = true;

      el.addEventListener('dragenter', function dragEnter(e) {
        console.log($scope.$id, 'dragEnter');
      }, false);
      el.addEventListener('dragleave', function dragEnter(e) {
        console.log($scope.$id, 'dragleave');
      }, false);

    }
  };
});
div[am-dnd] {
  border: 2px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <div am-dnd>
    <p>DRAG ME</p>
  </div>
  <div am-dnd>
    <h3>DRAG OVER THIS AREA</h3>
    <p>See the console, drag enter and leave are fired again and again while draging over
    </p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi quisquam, eaque, iure mollitia similique magnam voluptatem blanditiis distinctio nemo! Laboriosam porro iste maiores sequi magnam similique ad, in at. Omnis.</p>
  </div>

</div>

【问题讨论】:

    标签: angularjs html drag-and-drop


    【解决方案1】:

    我感觉“闪烁”问题的根源在于第二个 am-dnd 指令的每个子元素都发生了 dragenter/dragleave 事件。有一个 Stack Overflow 问题讨论了对此 here 的修复。

    您也许可以像这样声明 CSS 规则:

    .child-elements {
       pointer-events: none;
    }
    

    ...并在事件触发期间使用 jqLit​​e 将此类应用于 am-dnd 指令的所有子元素:

    element.children().addClass("child-elements");
    

    我做了一个JSFiddle,当第一个指令被拖到第二个指令上时,“闪烁”事件被最小化,但是第二个指令被拖到第一个指令上仍然存在一些问题。不过,我希望这能为您指明正确的方向。

    var app = angular.module('app', []);
    app.directive('amDnd', function () {
        return {
            scope: true,
            link: function (scope, element, attrs) {
                element.attr('draggable', 'true');
    
                element.on('dragenter', function () {
                    element.children().addClass("child-elements");
                    console.log('dragEnter');
                });
                element.on('dragleave', function () {
                    element.children().removeClass("child-elements");
                    console.log('dragleave');
                });
            }
        };
    });
    

    【讨论】:

    • 谢谢你的回答,它指出了我的问题,所以我可以解决它。您的解决方案有效且正确,但在我的项目中,我使用的是嵌套指令,因此我想出了更适合我需求的不同解决方案。再次感谢您,祝您有美好的一天;)
    • @Luckylooke 真棒 - 我很高兴能提供一些帮助。
    【解决方案2】:

    最适合我需要的解决方案:

    var app = angular.module('app', []);
    app.directive('amDnd', function() {
      return {
        scope: true,
        link: function($scope, $element, $attr) {
          var el = $element[0],
            counter = 0;
          el.draggable = true;
    
          el.addEventListener('dragenter', function dragEnter(e) {
            if (e.target === el && !counter) {
              console.log($scope.$id, 'dragEnter');
            }
            counter++;
          }, false);
          el.addEventListener('dragleave', function dragLeave(e) {
            counter--;
            if (e.target === el && !counter) {
              console.log($scope.$id, 'dragleave');
            }
          }, false);
    
        }
      };
    });
    div[am-dnd] {
      border: 2px solid red;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="app">
      <div am-dnd id='id1'>
        <p>DRAG ME</p>
      </div>
      <div am-dnd id='id2'>
        <h3>DRAG OVER THIS AREA</h3>
        <p>See the console, drag enter and leave are fired again and again while draging over
        </p>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi quisquam, eaque, iure mollitia similique magnam voluptatem blanditiis distinctio nemo! Laboriosam porro iste maiores sequi magnam similique ad, in at. Omnis.</p>
      </div>
    
    </div>

    【讨论】:

    • 由于复制粘贴错误(计数器--;丢失),我不得不编辑我的答案。现在应该没问题了
    猜你喜欢
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 2016-09-03
    • 2012-12-21
    相关资源
    最近更新 更多