Javascript 高级可拖动问题

Posted

技术标签:

【中文标题】Javascript 高级可拖动问题【英文标题】:Javascript Advanced Draggable Trouble 【发布时间】:2018-07-30 01:32:42 【问题描述】:

我正在制作一个播放列表用于演示目的。我已经设置了一个嵌套列表项的无序列表。 “draggable=true”处理程序使这些项目可拖动,效果很好。

这就是我卡住的地方;

一旦项目被点击,并准备好拖动。我需要用户对用户丢弃物品的位置有强烈的视觉反馈。标准化没有给出任何视觉反馈,只是将列表项放在其他项之间。我正在寻找一种方法来在视觉上将其他列表元素推到一边,或者至少在用户持有拖动项目的位置上突出显示边框。

解决此问题的最佳方法是什么?我在这里放了一些代码以防万一,但我要查找的内容超出了我编写的代码。

html

<ul>
    <li draggable="true" ondragstart="dragStarted(event)" ondragover="draggingOver(event)" ondrop="dropped(event)" ondragenter="dragEnter(event)"> 
        Item 1
    </li>
    <li draggable="true" ondragstart="dragStarted(event)" ondragover="draggingOver(event)" ondrop="dropped(event)" ondragenter="dragEnter(event)"> 
        Item 2
    </li>
    <li draggable="true" ondragstart="dragStarted(event)" ondragover="draggingOver(event)" ondrop="dropped(event)" ondragenter="dragEnter(event)"> 
        Item 3
    </li>       
</ul>

JS

var source; 

function dragStarted(e)
    source = e.target;
    e.dataTransfer.setData("text/plain", e.target.innerHTML);
    e.dataTransfer.effectAllowed = "move";



function draggingOver(e)
    e.preventDefault();
    e.dataTransfer.dropEffect = "move";



function dropped(e)
    e.preventDefault();
    e.stopPropagation();
    if (e.target.localName === 'li') 
        source.innerHTML = e.target.innerHTML;
        e.target.innerHTML = e.dataTransfer.getData("text/plain");
    

如何添加代码,让我能够以项目之间突出显示的边框的形式设计视觉反馈。

【问题讨论】:

最好放置一个完整且可验证的示例,而不仅仅是一些代码。 我已更改代码以更有效地反映问题。 【参考方案1】:

检查这两个例子。

首先只是在拖动某些东西时突出显示悬停项目的边框。它使用dragenterdragleave 事件来添加和删除over css 类。

var source; 

var items = document.querySelectorAll('li');
for (item of items) 
  item.addEventListener('dragstart', dragStarted, false);
  item.addEventListener('drop', dropped, false);
  item.addEventListener('dragover', draggingOver, false);
  item.addEventListener('dragenter', dragEnter, false);
  item.addEventListener('dragleave', dragLeave, false);

document.getElementById("list").addEventListener('mouseleave', dropped, false);

function dragEnter(e)
  this.classList.add('over');


function dragLeave(e)
  this.classList.remove('over');


function dragStarted(e)
  source = e.target;
  e.dataTransfer.setData("text/plain", e.target.innerHTML);
  e.dataTransfer.effectAllowed = "move";
  this.classList.add("over");
  this.style.opacity = '0.4';


function draggingOver(e)
  e.preventDefault();
  e.dataTransfer.dropEffect = "move";


function dropped(e)
  e.preventDefault();
  e.stopPropagation();
  source.style.opacity = '1.0';
  if (e.target.localName === 'li') 
    source.innerHTML = e.target.innerHTML;
    e.target.innerHTML = e.dataTransfer.getData("text/plain");
  
  this.classList.remove("over");
  source.classList.remove("over");
ul  list-style-type: none; 

li 
  border: 1px solid #000;
  border-radius: 3px;
  text-decoration: none;
  padding: 2px 2px 2px 10px;
  margin: 1px;
  width: 300px;
  transition: 0.2s ease-in-out;


li.over 
  border: 1px dashed orange;
<ul id="list">
  <li draggable="true">Sun Shining On The Moon</li>
  <li draggable="true">Airglow</li>
  <li draggable="true">Diffuse reflection</li>
  <li draggable="true">Starlight</li>
</ul>

我认为,第二个示例更接近您的需要。它使用 javascript insertBefore 方法替换 dragenter 事件上的项目。

var source; 

var items = document.querySelectorAll('li');
for (item of items) 
  item.addEventListener('dragstart', dragStarted, false);
  item.addEventListener('drop', dropped, false);
  item.addEventListener('dragover', draggingOver, false);
  item.addEventListener('dragenter', dragEnter, false);

document.getElementById("list").addEventListener('mouseleave', dropped, false);

function isBefore(a, b) 
    if (a.parentNode == b.parentNode) 
        for (var cur = a; cur; cur = cur.previousSibling) 
            if (cur === b)  
                return true;
            
        
    
    return false;
 

function dragEnter(e) 
    if (isBefore(source, e.target)) 
        e.target.parentNode.insertBefore(source, e.target);
    
    else 
        e.target.parentNode.insertBefore(source, e.target.nextSibling);
    


function dragStarted(e)
  e.dataTransfer.setData("text/plain", e.target.innerHTML);
  e.dataTransfer.effectAllowed = "move";
  this.classList.add("over");
  this.style.opacity = '0.4';
  source = this;


function draggingOver(e)
  e.preventDefault();
  e.dataTransfer.dropEffect = "move";


function dropped(e)
  source.style.opacity = '1.0';
  source.classList.remove("over");
ul  list-style-type: none; 

li 
  border: 1px solid #000;
  border-radius: 3px;
  text-decoration: none;
  padding: 2px 2px 2px 10px;
  margin: 1px;
  width: 300px;
  transition: 0.2s ease-in-out;


li.over 
  border: 1px dashed orange;
  transform: scale(0.97);
<ul id="list">
  <li draggable="true">Sun Shining On The Moon</li>
  <li draggable="true">Airglow</li>
  <li draggable="true">Diffuse reflection</li>
  <li draggable="true">Starlight</li>
</ul>

【讨论】:

以上是关于Javascript 高级可拖动问题的主要内容,如果未能解决你的问题,请参考以下文章

javascript高级教程JavaScript Number 对象

纯javascript可拖动元素

《javascript高级程序设计》笔记三

在本机javascript中创建一个可拖动的div [重复]

javascript - 如何制作多个可拖动的克隆?

使 javascript 弹出窗口可拖动