HTML5中的多个丢弃事件 [英] Multiple drop events in HTML5

查看:92
本文介绍了HTML5中的多个丢弃事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在HTML5中创建一个拖放功能,我可以从一个列表拖动到另一个列表。我有一个包含可拖动项目的列表,另一个列表包含添加了拖放事件的项目。问题是,无论我放入什么元素,最后添加的drop事件都是被调用的事件。

I'm trying to create a drag and drop feature in HTML5 where I can drag from one list to another. I have one list with draggable items and another list with items that have drop events added. The problem is, regardless of what element I drop onto, the last drop event that was added is the one that gets called.

感谢您提供任何帮助或建议。

Thanks for any help or suggestions.

我在下面提供了我的代码:

I've included my code below:

<!DOCTYPE html>

<head>
<title>List Conversion Test</title>

<style type="text/css">

#list, #cart {
  display: inline;
  float: left;
  border: 1px solid #444;
  margin: 25px;
  padding: 10px;
}

#list p {
  background-color: #036;
  color: #fff;
}
#cart p {
  background-color: #363;
  color: #fff;
}

.listitem {

}

.listitem_done {
  text-decoration: line-through;
}

.product {
  background-color: #CCC;
}

.product_over {
  background-color: #363;
}

</style>


<script type="text/javascript" src="http://html5demos.com/js/h5utils.js"></script>

</head>

<body>

<article>
  <div id="list">
    <p>On My List</p>
    <ul>
      <li class="listitem" id="L001">Shopping List Item #1</li>
      <li class="listitem" id="L002">Shopping List Item #2</li>
    </ul>
    <div id="done">
      <p>In My Cart</p>
      <ul></ul>
    </div>
  </div>

  <div id="cart">
    <p>Cart</p>
    <ul>
      <li class="product" id="P001">Product #1</li>
      <li class="product" id="P002">Product #2</li>
    </ul>
  </div>

</article>
<script>

  // make list items draggable
  var list = document.querySelectorAll('li.listitem'), thisItem = null;
  for (var i = 0; i < list.length; i++) {
    thisItem = list[i];

    thisItem.setAttribute('draggable', 'true');

    addEvent(thisItem, 'dragstart', function (e) {
      e.dataTransfer.effectAllowed = 'copy';
      e.dataTransfer.setData('Text', this.id);
    });
  }


  // give products drop events
  var products = document.querySelectorAll('li.product'), thisProduct = null;
  for (var i = 0; i < products.length; i++) {
    thisProduct = products[i];

    addEvent(thisProduct, 'dragover', function (e) {
      if (e.preventDefault) e.preventDefault();
      this.className = 'product_over';
      e.dataTransfer.dropEffect = 'copy';
      return false;
    });

    addEvent(thisProduct, 'dragleave', function () {
     this.className = 'product';
    });

    addEvent(thisProduct, 'drop', function (e) {
      //alert(thisProduct.id);
      if (e.stopPropagation) e.stopPropagation();
      var thisItem = document.getElementById(e.dataTransfer.getData('Text'));
      thisItem.parentNode.removeChild(thisItem);
      thisProduct.className = 'product';
      handleDrop(thisItem, thisProduct);
      return false;
    });

  }

  // handle the drop
  function handleDrop(i, p) {
    alert(i.id + ' to ' + p.id);
    var done = document.querySelector('#done > ul');
    done.appendChild(i);
    i.className = 'listitem_done';
  } 


</script>

</body>
</html>


推荐答案

这就是定义函数通常是个坏主意的原因循环中的(例如回调函数)。您在循环中分配 thisProduct ,但它将在下一次循环迭代时重新分配。设置闭包的方式,每个回调绑定到相同的变量 thisProduct ,并将使用最新值。

This is why it's often a bad idea to define functions (such as callback functions) within a loop. You're assigning thisProduct within the loop, but it will be reassigned for the next iteration of the loop. The way your closures are set up, each callback is bound to the same variable thisProduct, and will use the latest value.

一种可能的解决方法是创建一个新的闭包,其中需要 thisProduct ,例如

One possible fix is to create a new closure where thisProduct is needed such as

(function(thisProduct) {
    addEvent(thisProduct, 'drop', function (e) {
      //alert(thisProduct.id);
      if (e.stopPropagation) e.stopPropagation();
      var thisItem = document.getElementById(e.dataTransfer.getData('Text'));
      thisItem.parentNode.removeChild(thisItem);
      thisProduct.className = 'product';
      handleDrop(thisItem, thisProduct);
      return false;
    });
}(thisProduct));

jsFiddle 现在似乎对我有用。有关详细说明,请参见此处

This jsFiddle seems to work for me now. See here for more explanation.

这篇关于HTML5中的多个丢弃事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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