Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to drag a button element in Firefox

I'm having an issue with a project I'm working on. It's a web application with an interface that partly exists out of drag 'n drop elements.

The issue is that the draggable div elements work fine but the button elements won't engage the drag in Firefox but they do work in Chrome. I think this might have something to do with the way Firefox handles the already existing events of the button, which is probably different than how Chrome does this.

I know I can use jQuery UI instead but this project does not allow me to.

Here is a jsfiddle of my problem: http://jsfiddle.net/MJN6c/6/

Does anyone know how I can get the drag events to trigger on buttons in Firefox?

The code:

var stage = document.querySelector('#drop');
var btnsAni = document.querySelectorAll('.btn-ani');

[].forEach.call(btnsAni, function (btn) {
    btn.addEventListener('dragstart', dragStart, false);
    btn.addEventListener('dragend', dragEnd, false);
});

stage.addEventListener('dragenter', dragEnter, false);
stage.addEventListener('dragleave', dragLeave, false);
stage.addEventListener('dragover', dragOver, false);
stage.addEventListener('drop', dragDrop, false);

function dragStart(e) {
    if (e.stopPropagation) e.stopPropagation();
    e.dataTransfer.effectAllowed = 'copy';
    e.dataTransfer.setData('Text', this.id);

    return false;
}

function dragEnd(e) {
    e.preventDefault();
    if (e.stopPropagation) e.stopPropagation();

    return false;
}

function dragEnter(e) {
    e.preventDefault();
    if (e.stopPropagation) e.stopPropagation();

    return false;
}

function dragOver(e) {
    e.preventDefault();
    if (e.stopPropagation) e.stopPropagation();
    e.dataTransfer.dropEffect = 'copy';

    return false;
}

function dragLeave(e) {
    e.preventDefault();
    if (e.stopPropagation) e.stopPropagation();

    return false;
}

function dragDrop(e) {
    e.preventDefault();
    if (e.stopPropagation) e.stopPropagation();

    alert("Dropped!");
}
like image 984
Levi Avatar asked Apr 12 '13 09:04

Levi


2 Answers

This looks like a bug with FF, https://bugzilla.mozilla.org/show_bug.cgi?id=568313.
As an aside, all XUL elements are "draggable" by default. https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_operations#draggableattribute

like image 163
Josh Avatar answered Oct 14 '22 10:10

Josh


In few words: this is the issue with Firefox, not with your code. Drag event doesn't fire on button, but fires on div.

I could handle this issue in few steps:

1) Add a wrapper for button

2) Add ::after pseudo-element to the wrapper

3) Stretch ::after to fill the parent:

.wrapper {
   position: relative;

   &:after {
    content: '';
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    position: absolute;
  }
}

This way ::after will be out of normal flow and wrapper's size will be calculated by button's size (as usually). If the button doesn't have defined z-index, ::after will be placed automatically on top of the button (on z-axis). This will cause firing of drag events on wrapper, not the button. And the issue is solved!

You probably would like to fix some styles after adding a wrapper (for example, you have to move :hover and :focus pseudo-classes to the wrapper).

like image 20
Hello Deadline Avatar answered Oct 14 '22 10:10

Hello Deadline