Firefox html5拖放不起作用

时间:2013-09-18 21:51:38

标签: html5 angularjs drag-and-drop draggable html5-draggable

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

我有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 个答案:

答案 0 :(得分:2)

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