【问题标题】:Drag and drop example - HTML5拖放示例 - HTML5
【发布时间】:2011-11-08 15:57:07
【问题描述】:

我正在尝试从 WWWC (here) 中学习拖放示例,并且我可以在拖走时将列表项从原始列表中删除,但不会出现在新列表中。有什么想法为什么不呢?我已经尝试过 Safari 5.1.1、Chrome 15 和 Firefox 7.0.1。

    <head>
        <title>Drag 'N Drop</title>
    </head>

    <p>What fruits do you like?</p>
    <ol ondragstart="dragStartHandler(event)" ondragend="dragEndHandler(event)">    
     <li draggable="true" data-value="fruit-apple">Apples</li>
     <li draggable="true" data-value="fruit-orange">Oranges</li>
     <li draggable="true" data-value="fruit-pear">Pears</li>
    </ol>
    <script>
      var internalDNDType = 'text/plain'; // set this to something specific to your site
      function dragStartHandler(event) {
        if (event.target instanceof HTMLLIElement) {
          // use the element's data-value="" attribute as the value to be moving:
          event.dataTransfer.setData(internalDNDType, event.target.dataset.value);
          event.dataTransfer.effectAllowed = 'move'; // only allow moves
        } else {
          event.preventDefault(); // don't allow selection to be dragged
        }
      }
      function dragEndHandler(event) {
        // remove the dragged element
        event.target.parentNode.removeChild(event.target);

      }
    </script>

    <p>Drop your favorite fruits below:</p>
    <div dropzone="move s:text/plain" ondrop="dropHandler(event)">
        <ol dropzone="move s:text/plain" ondrop="dropHandler(event)">
         <!-- don't forget to change the "text/x-example" type to something
         specific to your site -->
            <li>Bananas</li>
        </ol>
        </br>
        </br>
        </br>
    </div>
    <script>
      var internalDNDType = 'text/plain'; // set this to something specific to your site
      function dropHandler(event) {
        var li = document.createElement('li');
        var data = event.dataTransfer.getData(internalDNDType);
        if (data == 'fruit-apple') {
          li.textContent = 'Apples';
        } else if (data == 'fruit-orange') {
          li.textContent = 'Oranges';
        } else if (data == 'fruit-pear') {
          li.textContent = 'Pears';
        } else {
          li.textContent = 'Unknown Fruit';
        }
        event.target.appendChild(li);
      }
    </script>

【问题讨论】:

标签: html drag-and-drop


【解决方案1】:

有几个问题。首先,您的 dropzone 需要取消拖动事件:

<ol dropzone="move s:text/plain" ondrop="dropHandler(event)" ondragover="dragOverHandler(event)">

function dragOverHandler(event) {
    event.preventDefault();
    return false;
}

其次,您的 dropHandler 处理函数将被触发多次,因为大多数情况下,放置目标将是 li 元素而不是 ol(也可能是 @987654327 @,但我忽略了那个元素)。所以要么添加代码只处理ol处的事件,要么取消dropHandlerwith stopPropagation处的事件。

最后,删除项目时的默认操作(至少在 Firefox 中,没有检查其他浏览器)是尝试导航到由 text/plain 值表示的 URL,因此您应该添加一些 event.preventDefault()在可能的地方。这是一个更新的dropHandler 函数:

function dropHandler(event) {
    var li = document.createElement('li');
    var data = event.dataTransfer.getData(internalDNDType);
    if (data == 'fruit-apple') {
      li.textContent = 'Apples';
    } else if (data == 'fruit-orange') {
      li.textContent = 'Oranges';
    } else if (data == 'fruit-pear') {
      li.textContent = 'Pears';
    } else {
      li.textContent = 'Unknown Fruit';
    }
    event.target.appendChild(li);
    event.stopPropagation();
    event.preventDefault();
    return false;
}

Here's my updated version.

【讨论】:

  • 您提供的示例仍然没有在您删除项目时将其添加到列表中。我删除了
  • 以确保它被放到有序列表中,但仍然没有
  • @Chris 是的,您在哪个浏览器中尝试过? (这里是 Firefox 7.0.1,现在是 8.0,因为它在我帮助时更新->关于)
  • @Chris 我想我可能会看到问题所在:无论是否成功放置,都会触发 'dragend` 事件,因此如果你放置在不是你放置的地方,则元素会被删除区。在drop 事件中删除源元素可能更容易。
  • @Chris 你搞定了吗?你看过我的 jsFiddle 例子吗?
  • 【解决方案2】:

    简短的回答是,您还需要向放置区域添加一个拖动侦听器,以允许放置操作发生。

    function handleDragOver(e) {
      if (e.preventDefault) {
        e.preventDefault(); // Necessary. Allows us to drop.
      }
    
      e.dataTransfer.dropEffect = 'move';
    
      return false;
    }
    

    这一步你有详细的解释tutorial(虽然该教程中的元素既是可拖动元素又是放置区域)

    但是,克里斯,尽管我很高兴您正在尝试使用原生 HTML5 拖放功能,但当我说您的代码在标记级别和 Javascript 级别都有太多严重错误时,请接受我的拙见。即缺少标签、不存在的结束标签、错误的属性命名空间、链式元素中的重复侦听器、同一范围内的重复变量等。我建议先进行几次代码审查。

    【讨论】:

    • 代码是在链接教程中给出的,所以显然不是生产级代码,但鉴于它是由制定 HTML 标准的组织提供的,我认为它至少可以工作。
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签