列表使用HTML5 Drag'n'Drop进行排序 - 根据鼠标在上方或下方进行排序 [英] List Sorting with HTML5 Drag'n'Drop - Drop Above or Below Depending on Mouse

查看:108
本文介绍了列表使用HTML5 Drag'n'Drop进行排序 - 根据鼠标在上方或下方进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个可排序列表,以避免在数据库中手动输入排序顺序号。它通过HTML5的拖放功能工作,即Javascript中的新拖* 事件。

I am working on a sortable list, to avoid having to manually type in sorting order numbers in a database. It works via HTML5's drag'n'drop functionality, i.e. the new drag* events in Javascript.

我目前让它在大多数情况下都有效。我可以点击,然后拖动,它会自行排序。

I currently have it working for the most part. I can click, and drag, and it'll sort itself.

从我所知道的, drop ,以及 dragstart dragend 事件,只知道他们要进入的元素。他们无法判断鼠标是否位于掉区的上半部分或下半部分。

From what I can tell, the drop, along with the dragstart and dragend events, only are aware of the element they are going into. They can't tell if the mouse is on the top half of the dropzone, or the bottom half.

我想要的是,当我徘徊在列表项的上半部分,用于将拖动的内容放置在项目上方。然后,如果我将鼠标悬停在下半部分上,则将拖动的内容放置在项目下方。

What I'd like, is when I'm hovering over the top half of a list item, for the dragged content to be placed ABOVE the item. Then if I'm hovering over the bottom half, for the dragged content to be placed BELOW the item.

在下面的屏幕截图中,我展示了我的代码的工作(简化)示例。我在放置目标上使用 border-bottom 来显示它是目标。注意当项目1在项目2之上,项目2在底部点亮,无论我是否在上半部分或下半部分上空盘旋。

In the screencap below, I show a working (simplified) example of my code. I'm using a border-bottom on the drop target to show that it's the target. Notice how when "Item 1" is above "Item 2", "Item 2" is lit up on the bottom, regardless of if I'm hovering over the top half or bottom half.

代码

var dragging = null;

document.addEventListener('dragstart', function(event) {
		dragging = event.target;
    event.dataTransfer.setData('text/html', dragging);
});

document.addEventListener('dragover', function(event) {
    event.preventDefault();
});

document.addEventListener('dragenter', function(event) {
    event.target.style['border-bottom'] = 'solid 4px blue';
});

document.addEventListener('dragleave', function(event) {
    event.target.style['border-bottom'] = '';
});

document.addEventListener('drop', function(event) {
    event.preventDefault();
    event.target.style['border-bottom'] = '';
    event.target.parentNode.insertBefore(dragging, event.target.nextSibling);
});

ul {
  margin:0;
  padding:0
}
li {
  cursor:move;
  display:block;
  padding:20px 10px;
  background:white;
  border-bottom:solid 1px gray;
}

<ul>
    <li draggable="true" class="sortable-bulk">List Item 1</li>
    <li draggable="true" class="sortable-bulk">List Item 2</li>
    <li draggable="true" class="sortable-bulk">List Item 3</li>
    <li draggable="true" class="sortable-bulk">List Item 4</li>
    <li draggable="true" class="sortable-bulk">List Item 5</li>
    <li draggable="true" class="sortable-bulk">List Item 6</li>
    <li draggable="true" class="sortable-bulk">List Item 7</li>
    <li draggable="true" class="sortable-bulk">List Item 8</li>
    <li draggable="true" class="sortable-bulk">List Item 9</li>
    <li draggable="true" class="sortable-bulk">List Item 10</li>
</ul>

有没有办法让它在上方或下方下降,而不是总是低于,拖动时取决于鼠标位置?

Is there a way I can have it drop either above or below, not always below, depending on the mouse position while dragging?

推荐答案

答案



所以在命运的扭曲中,对另一个问题的评论回应指出了我的答案。 狼战值得信赖指向我正确的事件和方法。

Answer

So in a twist of fate, a comment response on another question pointed me to the answer here. wolf-war deserves credit here for pointing me to the right event and method.

无论如何,回答问题。解决方案在于使用 dragover 事件,而不是使用 dragenter 事件。 dragover 只要你在徘徊就继续开枪。

Anyway, on to the answer. The solution lies in using the dragover event, rather than using the dragenter event. dragover keeps firing as long as you are hovering.

我们摆脱 dragenter 代码:

document.addEventListener('dragenter', function(event) {
    event.target.style['border-bottom'] = 'solid 4px blue';
});

将其替换为:

document.addEventListener('dragover', function(event) {
    event.preventDefault();
    var bounding = event.target.getBoundingClientRect()
    var offset = bounding.y + (bounding.height/2);
    if ( event.clientY - offset > 0 ) {
        event.target.style['border-bottom'] = 'solid 4px blue';
        event.target.style['border-top'] = '';
    } else {
        event.target.style['border-top'] = 'solid 4px blue';
        event.target.style['border-bottom'] = '';
    }
});

然后在 drop 部分,我们检查查看放置目标所具有的边界,并使用它来插入上方或下方的拖动内容。

Then in the drop section, we check to see which border the drop target has, and use that to insert the dragged content either above or below.

var dragging = null;

document.addEventListener('dragstart', function(event) {
		dragging = event.target;
    event.dataTransfer.setData('text/html', dragging);
});

document.addEventListener('dragover', function(event) {
    event.preventDefault();
    //window.requestAnimationFrame(function(){
    	var bounding = event.target.getBoundingClientRect()
      var offset = bounding.y + (bounding.height/2);
      if ( event.clientY - offset > 0 ) {
      	event.target.style['border-bottom'] = 'solid 4px blue';
        event.target.style['border-top'] = '';
      } else {
        event.target.style['border-top'] = 'solid 4px blue';
        event.target.style['border-bottom'] = '';
      }
    //});
});

document.addEventListener('dragleave', function(event) {
    event.target.style['border-bottom'] = '';
    event.target.style['border-top'] = '';
});

document.addEventListener('drop', function(event) {
    event.preventDefault();
    if ( event.target.style['border-bottom'] !== '' ) {
      event.target.style['border-bottom'] = '';
      event.target.parentNode.insertBefore(dragging, event.target.nextSibling);
    } else {
      event.target.style['border-top'] = '';
      event.target.parentNode.insertBefore(dragging, event.target);
    }
});

ul {
  margin:0;
  padding:0
}
li {
  cursor:move;
  display:block;
  padding:20px 10px;
  background:white;
  border-bottom:solid 1px gray;
}

<ul>
    <li draggable="true" class="sortable-bulk">List Item 1</li>
    <li draggable="true" class="sortable-bulk">List Item 2</li>
    <li draggable="true" class="sortable-bulk">List Item 3</li>
    <li draggable="true" class="sortable-bulk">List Item 4</li>
    <li draggable="true" class="sortable-bulk">List Item 5</li>
    <li draggable="true" class="sortable-bulk">List Item 6</li>
    <li draggable="true" class="sortable-bulk">List Item 7</li>
    <li draggable="true" class="sortable-bulk">List Item 8</li>
    <li draggable="true" class="sortable-bulk">List Item 9</li>
    <li draggable="true" class="sortable-bulk">List Item 10</li>
</ul>

这篇关于列表使用HTML5 Drag'n'Drop进行排序 - 根据鼠标在上方或下方进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆