javascript - Dragula:如何始终将项目移动到列表末尾

标签 javascript dragula

我正在使用 Dragula 创建一个拖放页面。它运作得很好。但就我而言,我需要将该项目移动到列表的末尾。永远。

这是我的 JavaScript 代码

dragula([
        document.getElementById('left'),
        document.getElementById('right')
    ])

    .on('drag', function (el) {

        // add 'is-moving' class to element being dragged
        el.classList.add('is-moving');
        console.log(el.classList);
    })
    .on('dragend', function (el) {

        // remove 'is-moving' class from element after dragging has stopped
        el.classList.remove('is-moving');

        // add the 'is-moved' class for 600ms then remove it
        window.setTimeout(function () {
            el.classList.add('is-moved');
            window.setTimeout(function () {
                el.classList.remove('is-moved');
            }, 600);
        }, 100);
    });


var createOptions = (function () {
    var dragOptions = document.querySelectorAll('.drag-options');

    // these strings are used for the checkbox labels
    var options = ['Research', 'Strategy', 'Inspiration', 'Execution'];

    // create the checkbox and labels here, just to keep the html clean. append the <label> to '.drag-options'
    function create() {
        for (var i = 0; i < dragOptions.length; i++) {

            options.forEach(function (item) {
                var checkbox = document.createElement('input');
                var label = document.createElement('label');
                var span = document.createElement('span');
                checkbox.setAttribute('type', 'checkbox');
                span.innerHTML = item;
                label.appendChild(span);
                label.insertBefore(checkbox, label.firstChild);
                label.classList.add('drag-options-label');
                dragOptions[i].appendChild(label);
            });

        }
    }

    return {
        create: create
    }


}());

var showOptions = (function () {

    // the 3 dot icon
    var more = document.querySelectorAll('.drag-header-more');

    function show() {
        // show 'drag-options' div when the more icon is clicked
        var target = this.getAttribute('data-target');
        var options = document.getElementById(target);
        options.classList.toggle('active');
    }


    function init() {
        for (i = 0; i < more.length; i++) {
            more[i].addEventListener('click', show, false);
        }
    }

    return {
        init: init
    }
}());

var leftList = document.querySelector('#left');
var rightList = document.querySelector('#right');
var list = document.querySelectorAll('#right li, #left li');
var itemMoving = undefined;
for (var i = 0; i < list.length; i++) {
    list[i].addEventListener('click', function () {
        if (this.parentNode.id == 'right') {
            itemMoving = this;
            leftList.appendChild(this);
        } else {
            itemMoving = this;
            rightList.appendChild(this);
        }

        // add the 'is-moved' class for 600ms then remove it
        window.setTimeout(function () {
            itemMoving.classList.add('is-moved');
            window.setTimeout(function () {
                itemMoving.classList.remove('is-moved');
            }, 600);
        }, 100);

    });
}

createOptions.create();
showOptions.init();

This is my running code On Code Pen

最佳答案

您可以像这样 Hook dragula的shadow事件,强制将拖动元素的影子副本附加到容器:

.on('shadow', function (el, container, source) {
  // check if the shadow copy is not already the last child of the container
  if (el !== container.children[container.children.length-1]) {
    // otherwise: make it so
    container.appendChild(el);
  }
})

工作示例(全屏最佳观看):

dragula([
    document.getElementById('left'),
    document.getElementById('right')
  ])

  .on('drag', function(el) {

    // add 'is-moving' class to element being dragged
    el.classList.add('is-moving');
  })
  .on('shadow', function(el, container, source) {
    if (el !== container.children[container.children.length - 1]) {
      container.appendChild(el);
    }
  })
  .on('dragend', function(el) {

    // remove 'is-moving' class from element after dragging has stopped
    el.classList.remove('is-moving');

    // add the 'is-moved' class for 600ms then remove it
    window.setTimeout(function() {
      el.classList.add('is-moved');
      window.setTimeout(function() {
        el.classList.remove('is-moved');
      }, 600);
    }, 100);
  });


var createOptions = (function() {
  var dragOptions = document.querySelectorAll('.drag-options');

  // these strings are used for the checkbox labels
  var options = ['Research', 'Strategy', 'Inspiration', 'Execution'];

  // create the checkbox and labels here, just to keep the html clean. append the <label> to '.drag-options'
  function create() {
    for (var i = 0; i < dragOptions.length; i++) {

      options.forEach(function(item) {
        var checkbox = document.createElement('input');
        var label = document.createElement('label');
        var span = document.createElement('span');
        checkbox.setAttribute('type', 'checkbox');
        span.innerHTML = item;
        label.appendChild(span);
        label.insertBefore(checkbox, label.firstChild);
        label.classList.add('drag-options-label');
        dragOptions[i].appendChild(label);
      });

    }
  }

  return {
    create: create
  }


}());

var showOptions = (function() {

  // the 3 dot icon
  var more = document.querySelectorAll('.drag-header-more');

  function show() {
    // show 'drag-options' div when the more icon is clicked
    var target = this.getAttribute('data-target');
    var options = document.getElementById(target);
    options.classList.toggle('active');
  }


  function init() {
    for (i = 0; i < more.length; i++) {
      more[i].addEventListener('click', show, false);
    }
  }

  return {
    init: init
  }
}());

var leftList = document.querySelector('#left');
var rightList = document.querySelector('#right');
var list = document.querySelectorAll('#right li, #left li');
var itemMoving = undefined;
for (var i = 0; i < list.length; i++) {
  list[i].addEventListener('click', function() {
    if (this.parentNode.id == 'right') {
      itemMoving = this;
      leftList.appendChild(this);
    } else {
      itemMoving = this;
      rightList.appendChild(this);
    }

    // add the 'is-moved' class for 600ms then remove it
    window.setTimeout(function() {
      itemMoving.classList.add('is-moved');
      window.setTimeout(function() {
        itemMoving.classList.remove('is-moved');
      }, 600);
    }, 100);

  });
}

createOptions.create();
showOptions.init();
* {
  box-sizing: border-box;
}

body {
  background: #33363D;
  color: white;
  font-family: 'Lato';
  font-weight: 300;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
}

.drag-container {
  max-width: 1000px;
  margin: 20px auto;
}

.drag-list {
  display: flex;
  align-items: flex-start;
}

@media (max-width: 690px) {
  .drag-list {
    display: block;
  }
}

.drag-column {
  flex: 1;
  margin: 0 10px;
  position: relative;
  background: rgba(0, 0, 0, 0.2);
  overflow: hidden;
}

@media (max-width: 690px) {
  .drag-column {
    margin-bottom: 30px;
  }
}

.drag-column h2 {
  font-size: 0.8rem;
  margin: 0;
  text-transform: uppercase;
  font-weight: 600;
}

.drag-column-on-hold .drag-column-header,
.drag-column-on-hold .is-moved,
.drag-column-on-hold .drag-options {
  background: #FB7D44;
}

.drag-column-in-progress .drag-column-header,
.drag-column-in-progress .is-moved,
.drag-column-in-progress .drag-options {
  background: #2A92BF;
}

.drag-column-needs-review .drag-column-header,
.drag-column-needs-review .is-moved,
.drag-column-needs-review .drag-options {
  background: #F4CE46;
}

.drag-column-approved .drag-column-header,
.drag-column-approved .is-moved,
.drag-column-approved .drag-options {
  background: #00B961;
}

.drag-column-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px;
}

.drag-inner-list {
  min-height: 50px;
}

.drag-item {
  margin: 10px;
  height: 100px;
  background: rgba(0, 0, 0, 0.4);
  transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

.drag-item.is-moving {
  -webkit-transform: scale(1.5);
  transform: scale(1.5);
  background: rgba(0, 0, 0, 0.8);
}

.drag-header-more {
  cursor: pointer;
}

.drag-options {
  position: absolute;
  top: 44px;
  left: 0;
  width: 100%;
  height: 100%;
  padding: 10px;
  -webkit-transform: translateX(100%);
  transform: translateX(100%);
  opacity: 0;
  transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1);
}

.drag-options.active {
  -webkit-transform: translateX(0);
  transform: translateX(0);
  opacity: 1;
}

.drag-options-label {
  display: block;
  margin: 0 0 5px 0;
}

.drag-options-label input {
  opacity: 0.6;
}

.drag-options-label span {
  display: inline-block;
  font-size: 0.9rem;
  font-weight: 400;
  margin-left: 5px;
}


/* Dragula CSS  */

.gu-mirror {
  position: fixed !important;
  margin: 0 !important;
  z-index: 9999 !important;
  opacity: 0.8;
  list-style-type: none;
}

.gu-hide {
  display: none !important;
}

.gu-unselectable {
  -webkit-user-select: none !important;
  -moz-user-select: none !important;
  -ms-user-select: none !important;
  user-select: none !important;
}

.gu-transit {
  opacity: 0.2;
}


/* Demo info */

.section {
  padding: 20px;
  text-align: center;
}

.section a {
  color: white;
  text-decoration: none;
  font-weight: 300;
}

.section h4 {
  font-weight: 400;
}

.section h4 a {
  font-weight: 600;
}

.imgProfile {
  position: relative;
  left: 4px;
  top: 10px;
  height: 50px;
  width: 50px;
  border-radius: 50%;
}

.nomeProfile {
  position: relative;
  left: 66px;
  top: -47px;
  height: 44px;
}
<div class="drag-container">
  <ul class="drag-list">

    <li class="drag-column drag-column-approved">
      <span class="drag-column-header">
					<h2>Disponível</h2>
				</span>
      <div class="drag-options" id="options4"></div>
      <ul class="drag-inner-list" id="left">
        <li class="drag-item">
          <img class="imgProfile" src="https://storage.googleapis.com/montu-bucket/00_base/base_img_avatar.png" alt="Avatar">
          <h4 class="nomeProfile">User A</h4>
        </li>
        <li class="drag-item">
          <img class="imgProfile" src="https://storage.googleapis.com/montu-bucket/00_base/base_img_avatar.png" alt="Avatar">
          <h4 class="nomeProfile">User B</h4>
        </li>
        <li class="drag-item">
          <img class="imgProfile" src="https://storage.googleapis.com/montu-bucket/00_base/base_img_avatar.png" alt="Avatar">
          <h4 class="nomeProfile">User C</h4>
        </li>
        <li class="drag-item">
          <img class="imgProfile" src="https://storage.googleapis.com/montu-bucket/00_base/base_img_avatar.png" alt="Avatar">
          <h4 class="nomeProfile">User D</h4>
        </li>
      </ul>
    </li>

    <li class="drag-column drag-column-on-hold">
      <span class="drag-column-header">
					<h2>Em Atendimento</h2>
				</span>

      <div class="drag-options" id="options1"></div>

      <ul class="drag-inner-list" id="right">
      </ul>
    </li>
  </ul>
</div>

<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/45226/dragula.min.js"></script>

为了使卷影副本保持在动态位置并且只在 drop 后追加项目,可以简单地将 shadow 更改为 drop,但从用户体验 Angular 来看看来,视觉教具应该代表真实的最终位置。

关于javascript - Dragula:如何始终将项目移动到列表末尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59337061/

相关文章:

javascript - 使用 grunt-ssh 下载远程资源

javascript - Angular + Dragula - 确认掉落事件

javascript - 如何使用 Meteor-Dragula 将容器的内容推送到数组中?

javascript - Window.onload 与脚本延迟

javascript - 将变量从 javascript 传递到 php 以实现地理定位功能

javascript - 如何设置 Filestack 安全上传图片?

javascript - dragula - 如何禁用在其父容器中的拖动

javascript - ng2-dragula 实现拖放一侧并排序和不同的模板

javascript - 如何在ipad上模拟点击和拖动操作?