列表使用HTML5进行排序拖放 - 根据鼠标

时间:2017-06-07 14:16:45

标签: javascript html5 drag-and-drop

背景

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

我目前大部分都在工作。我可以点击,拖动,然后自行排序。

问题

据我所知,drop以及dragstartdragend事件,只知道他们要进入的元素。他们无法判断鼠标是在dropzone的上半部分还是在下半部分。

我喜欢的是,当我将鼠标悬停在列表项的上半部分上时,将拖动的内容放在项目上方。然后,如果我将鼠标悬停在下半部分上,则将拖动的内容放置在项目下方。

目前:

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

enter image description here

代码



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>
&#13;
&#13;
&#13;

问题

根据拖动时的鼠标位置,有没有办法让它在上方或下方下降,而不是总是在下方?

1 个答案:

答案 0 :(得分:6)

答案

因此,在命运的扭曲中,对另一个问题的评论回应指出了我的答案。 wolf-war pointing me值得信赖Read more about array_search() in the docs到正确的事件和方法。

无论如何,回答问题。解决方案在于使用protected void Button_Set_Click(object sender, EventArgs e) { SPClabel.Text = Convert.ToString(DropDownList_Players.SelectedIndex); } 事件,而不是使用dragover事件。只要你在徘徊,dragenter就会继续射击。

代码更改问题代码

我们摆脱了dragover代码:

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
var dragging = null;

document.addEventListener('dragstart', function(event) {
    var target = getLI( event.target );
    dragging = target;
    event.dataTransfer.setData('text/plain', null);
    event.dataTransfer.setDragImage(self.dragging,0,0);
});

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

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

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

function getLI( target ) {
    while ( target.nodeName.toLowerCase() != 'li' && target.nodeName.toLowerCase() != 'body' ) {
        target = target.parentNode;
    }
    if ( target.nodeName.toLowerCase() == 'body' ) {
        return false;
    } else {
        return target;
    }
}
ul {
  margin:0;
  padding:0
}
li {
  cursor:move;
  display:block;
  padding:20px 10px;
  background:white;
  border-bottom:solid 1px gray;
}