admin管理员组

文章数量:1024615

I have a list of elements and in each element there is a handle control element. I can easily drag and drop the elements to reorder. However I'm unsure to limit the drag start to the handle element.

eg:

<ul>
    <li draggable="true" ondragstart="..." ondrop="..." ondragover="..."><div class="reorder"></div>Item 1</li>
    <li draggable="true" ondragstart="..." ondrop="..." ondragover="..."><div class="reorder"></div>Item 2</li>
    <li draggable="true" ondragstart="..." ondrop="..." ondragover="..."><div class="reorder"></div>Item 3</li>
</ul>

In the above code, I can click and drag on the handle element or the text "Item #" to reorder them.

I thought in the ondragstart function I could check if the class of the event.target is handle and if not do event.preventDefault() but it seems the target is always the li whether the drag starts from the div or li.

So is there a way to check if the mouse was over a child element on the ondragstart event

I have a list of elements and in each element there is a handle control element. I can easily drag and drop the elements to reorder. However I'm unsure to limit the drag start to the handle element.

eg:

<ul>
    <li draggable="true" ondragstart="..." ondrop="..." ondragover="..."><div class="reorder"></div>Item 1</li>
    <li draggable="true" ondragstart="..." ondrop="..." ondragover="..."><div class="reorder"></div>Item 2</li>
    <li draggable="true" ondragstart="..." ondrop="..." ondragover="..."><div class="reorder"></div>Item 3</li>
</ul>

In the above code, I can click and drag on the handle element or the text "Item #" to reorder them.

I thought in the ondragstart function I could check if the class of the event.target is handle and if not do event.preventDefault() but it seems the target is always the li whether the drag starts from the div or li.

So is there a way to check if the mouse was over a child element on the ondragstart event

Share Improve this question asked Aug 24, 2014 at 20:47 Jonathan.Jonathan. 55.6k55 gold badges197 silver badges300 bronze badges 1
  • I'm having the same issue, where you able to figure this one out? – Noitidart Commented Oct 9, 2014 at 20:51
Add a ment  | 

2 Answers 2

Reset to default 1

Im based on the ments of Mouser. See this example:

var object = document.querySelector('li');

var dragger = document.querySelector('li .reorder');

dragger.addEventListener('mousedown', function () {
  object.setAttribute('draggable','true');
});

dragger.addEventListener('mouseout', function () {
  object.removeAttribute('draggable');
});

http://codepen.io/anon/pen/qOWJYF

You have to solve this problem the other way around. Set the ondragstart on the div, then when the users clicks on the div, set draggable to true for the li. When dropped set draggable back to false. This way you dragging only happens when the users uses the reorder div. You can simply register the object into the global scope

 function dragStart(event) {
   globalDraggedElement = this.parentElement;
   this.parentElement.draggable = true;
 }

function dragOver(event) {

  if (globalDraggedElement != this) {
    //If the element is not the dragged element, show mouse drop cursor.
    //Else show forbidden to drop cursor, by default.
     event.preventDefault();
  }

}

function dragDrop(event) {
  if (globalDraggedElement != this) {
    //perform action!

  }
  globalDraggedElement.draggable = false;
  //Delete the element from the global scope.
  delete globalDraggedElement;
}

function dragEnd(event) {
        this.draggable = false;

}

var liElement = document.querySelectorAll("li[draggable='true']");
for (var i = 0; i < liElement.length; ++i) {
  liElement[i].children[0].addEventListener('dragstart', dragStart, false);
  liElement[i].addEventListener('dragenter', dragOver, false);
  liElement[i].addEventListener('dragover', dragOver, false);
  liElement[i].addEventListener('drop', dragDrop, false);
  liElement[i].addEventListener('dragend', dragEnd, false);
}

Please use the addEventListeners to add events. I used document.querySelectorAll to select all li elements with the draggable property set to true. helpful article at MDN dragdrop

I have a list of elements and in each element there is a handle control element. I can easily drag and drop the elements to reorder. However I'm unsure to limit the drag start to the handle element.

eg:

<ul>
    <li draggable="true" ondragstart="..." ondrop="..." ondragover="..."><div class="reorder"></div>Item 1</li>
    <li draggable="true" ondragstart="..." ondrop="..." ondragover="..."><div class="reorder"></div>Item 2</li>
    <li draggable="true" ondragstart="..." ondrop="..." ondragover="..."><div class="reorder"></div>Item 3</li>
</ul>

In the above code, I can click and drag on the handle element or the text "Item #" to reorder them.

I thought in the ondragstart function I could check if the class of the event.target is handle and if not do event.preventDefault() but it seems the target is always the li whether the drag starts from the div or li.

So is there a way to check if the mouse was over a child element on the ondragstart event

I have a list of elements and in each element there is a handle control element. I can easily drag and drop the elements to reorder. However I'm unsure to limit the drag start to the handle element.

eg:

<ul>
    <li draggable="true" ondragstart="..." ondrop="..." ondragover="..."><div class="reorder"></div>Item 1</li>
    <li draggable="true" ondragstart="..." ondrop="..." ondragover="..."><div class="reorder"></div>Item 2</li>
    <li draggable="true" ondragstart="..." ondrop="..." ondragover="..."><div class="reorder"></div>Item 3</li>
</ul>

In the above code, I can click and drag on the handle element or the text "Item #" to reorder them.

I thought in the ondragstart function I could check if the class of the event.target is handle and if not do event.preventDefault() but it seems the target is always the li whether the drag starts from the div or li.

So is there a way to check if the mouse was over a child element on the ondragstart event

Share Improve this question asked Aug 24, 2014 at 20:47 Jonathan.Jonathan. 55.6k55 gold badges197 silver badges300 bronze badges 1
  • I'm having the same issue, where you able to figure this one out? – Noitidart Commented Oct 9, 2014 at 20:51
Add a ment  | 

2 Answers 2

Reset to default 1

Im based on the ments of Mouser. See this example:

var object = document.querySelector('li');

var dragger = document.querySelector('li .reorder');

dragger.addEventListener('mousedown', function () {
  object.setAttribute('draggable','true');
});

dragger.addEventListener('mouseout', function () {
  object.removeAttribute('draggable');
});

http://codepen.io/anon/pen/qOWJYF

You have to solve this problem the other way around. Set the ondragstart on the div, then when the users clicks on the div, set draggable to true for the li. When dropped set draggable back to false. This way you dragging only happens when the users uses the reorder div. You can simply register the object into the global scope

 function dragStart(event) {
   globalDraggedElement = this.parentElement;
   this.parentElement.draggable = true;
 }

function dragOver(event) {

  if (globalDraggedElement != this) {
    //If the element is not the dragged element, show mouse drop cursor.
    //Else show forbidden to drop cursor, by default.
     event.preventDefault();
  }

}

function dragDrop(event) {
  if (globalDraggedElement != this) {
    //perform action!

  }
  globalDraggedElement.draggable = false;
  //Delete the element from the global scope.
  delete globalDraggedElement;
}

function dragEnd(event) {
        this.draggable = false;

}

var liElement = document.querySelectorAll("li[draggable='true']");
for (var i = 0; i < liElement.length; ++i) {
  liElement[i].children[0].addEventListener('dragstart', dragStart, false);
  liElement[i].addEventListener('dragenter', dragOver, false);
  liElement[i].addEventListener('dragover', dragOver, false);
  liElement[i].addEventListener('drop', dragDrop, false);
  liElement[i].addEventListener('dragend', dragEnd, false);
}

Please use the addEventListeners to add events. I used document.querySelectorAll to select all li elements with the draggable property set to true. helpful article at MDN dragdrop

本文标签: javascriptHTML5 Drag and drop parent from child elementStack Overflow