Firefox html5拖放不起作用

Posted

技术标签:

【中文标题】Firefox html5拖放不起作用【英文标题】:Firefox html5 drag and drop not working 【发布时间】:2013-09-23 20:19:35 【问题描述】:

我知道这里有很多类似的问题,但是,当他们付诸行动时,我仍然解决了同样的问题。

我有 2 个角度指令(拖放)和一个角度工厂(dndAPI)。这一切都基于fisshy's Angular Drag and Drop on github。

我终于让 Firefox 通过向事件添加数据来接受和拖动移动,但是我似乎无法阻止它执行默认行为(并将该数据作为 url 加载)。我也很抱歉,我根本无法让它在 jsfiddle 上工作......根本。如果有人看不出我是否做错了什么,我会再试一次。

angular.module('dragAndDrop', [])
.directive('drag',function (dndApi) 

    var drags = [],
        dragging = new RegExp('(\\s|^)dragging(\\s|$)');

    return 
        restrict: 'A',
        scope: 
            item: '=drag',
            whenStart: '&',
            whenEnd: '&',
            dropzones: '='
        ,
        link: function (scope, elem, attr, ctrl) 

            elem.bind('dragstart', function (e) 
                angular.element('query-tool-tip').removeClass('active');
                //if ( drags.length === 0 ) 
                drags = document.querySelectorAll('.drop');
                //

                angular.forEach(drags, function (value, key) 
                    if (scope.dropzones.indexOf(value.getAttribute('drop')) >= 0) 
                        value.className = value.className + ' dragging';
                    
                );

                elem.addClass('dragging');

                dndApi.setData(scope.item, scope.dropzones);

                e.originalEvent.dataTransfer.effectAllowed = 'move';

                //KEEPS FIREFOX FROM CRAPPING OUT:
                e.originalEvent.dataTransfer.setData( 'text/plain', 'stop' );

                scope.$apply(function () 
                    scope.whenStart( data: dndApi.getData() );
                );

            );

            elem.bind('dragleave', function(e));

            elem.bind('dragend', function (e) 

                elem.removeClass('dragging');

                angular.forEach(drags, function (value, key) 
                    value.className = value.className.replace(dragging, '');
                );

                scope.$apply(function () 
                    scope.whenEnd( data: dndApi.getData() );
                );

                dndApi.removeData();

                e.preventDefault();

            );

            elem[0].draggable = true;

            elem[0].className = elem[0].className + ' drag';

        
    ;
).directive('drop',function (dndApi) 

    var drags = [],
        dragging = new RegExp('(\\s|^)dragging(\\s|$)');

    return 
        scope: 
            drop: '=drop',
            whenDrop: '&',
            whenEnter: '&',
            whenLeave: '&',
            queryIndex: "=queryIndex",
            hideElem: '='
        ,
        link: function (scope, elem, attr, ctrl) 

            var left = elem[0].offsetLeft,
                right = left + elem[0].offsetWidth,
                top = elem[0].offsetTop,
                bottom = top + elem[0].offsetHeight;

            elem.bind('drop', function (e) 

               // e.originalEvent.preventDefault();


                //if (e.stopPropagation()) 
               // e.stopPropagation();
                //e.originalEvent.stopPropagation();
                    //e.preventDefault();
                //e.originalEvent.preventDefault();
                //

                e.originalEvent.dataTransfer.clearData();

                if (dndApi.getDropZones().indexOf(scope.drop) >= 0) 
                    scope.$apply(function () 
                        scope.whenDrop( data: dndApi.getData(), queryI: scope.queryIndex );
                    );
                

                if (drags.length === 0) 
                    drags = document.querySelectorAll('.drop');
                

                angular.forEach(drags, function (value, key) 

                    value.className = value.className.replace(dragging, '');

                );

                dndApi.removeData();

                e.stopPropagation();
                e.originalEvent.stopPropagation();
                e.preventDefault();
                e.originalEvent.preventDefault();

            );

            elem.bind('dragenter', function (e) 
                e.preventDefault();
                e.originalEvent.preventDefault();

                if (elem[0] == e.target) 
                    scope.$apply(function () 
                        scope.whenEnter( data: dndApi.getData() );
                    );
                


                return false;

            );

            elem.bind('dragleave', function (e) 
                e.preventDefault();
                e.originalEvent.preventDefault();


                if ((e.x < left || e.x > right) ||
                    (e.y < top || e.y > bottom)) 
                    scope.$apply(function () 
                        scope.whenLeave( data: dndApi.getData() );
                    );
                

                return false;
            );

            elem.bind('dragover', function (e) 

                //if (e.preventDefault) 
                    e.preventDefault();
                e.originalEvent.preventDefault();
                //

                return false;

            );

            elem[0].className = elem[0].className + ' drop';
            scope.$watch('hideElem', function () 
                if (scope.hideElem === true) 
                    elem.hide();
                 else 
                    elem.show();
                
            );

        
    ;
).factory('dndApi', function () 

    var dnd = 
        dragObject: ,
        dropzones: []
    ;

    return 
        setData: function (data, areas) 
            dnd.dragObject = data;
            dnd.dropzones = areas;
        ,
        removeData: function () 
            dnd.dragObject = null;
            dnd.dropZones = [];
        ,
        getData: function () 
            return dnd.dragObject;
        ,
        getDropZones: function () 
            return dnd.dropzones;
        
    ;
);

我已经完成了很多关于其他问题的建议。我已将 event.preventDefault() 添加到 dragenter 和 dragleave 点。然后当这不起作用时,我将它们添加到任何地方。我觉得这与我的 drop 方法有关。如果我将 event.prevendDefault() 放在绑定的开头,则不会执行其余代码。

任何建议,即使是我可能忽略的小事,都会有所帮助。

谢谢!

【问题讨论】:

【参考方案1】:

您在 drop 事件处理程序中调用 e.originalEvent.dataTransfer.clearData();,这将导致抛出异常(您将无权更改原始 dataTransfer 对象)。这会阻止e.originalEvent.preventDefault(); 被调用。

【讨论】:

太棒了!就是这样。我实际上不得不改变 e.originalEvent.preventDefault();到 e.preventDefault();

以上是关于Firefox html5拖放不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥 HTML5 拖放功能在 Firefox 中不起作用?

WinAppDriver中的拖放不起作用

MailChimp 内容块拖放不起作用

Selenium Webdriver - 拖放不起作用

jQuery拖放不起作用

使用自定义类型标识符拖放不起作用