Search code examples
javascriptvuejs2sortablejs

ondragover equivalent in Vue.Draggable (sortable.js)


Is there a way to detect if something is being dragged over an element? Or trigger the hover event? Found something about adding a class to the dragged over element via onMove, but it doesn't seem to work for me.


Solution

  • I made a JSBin with a solution: https://jsbin.com/xuwocis/edit?html,js,output

    var sorting = false;
    
    new Sortable(el, {
        onStart: function() {
            sorting = true;
        },
        onEnd: function() {
          sorting = false;
          // remove styling
          targetElement.style.backgroundColor = '';
        },
    //     forceFallback:true
    });
    
    // For native drag&drop
    targetElement.addEventListener('dragover', function(evt) {
        evt.preventDefault();
    });
    
    targetElement.addEventListener('dragenter', function(evt) {
        if (sorting && !targetElement.contains(evt.relatedTarget)) {
            // Here is where you add the styling of targetElement
            targetElement.style.backgroundColor = 'red';
        }
    });
    
    targetElement.addEventListener('dragleave', function(evt) {
        if (sorting && !targetElement.contains(evt.relatedTarget)) {
            // Here is where you remove the styling of targetElement
            targetElement.style.backgroundColor = '';
        }
    });
    
    
    // For fallback
    targetElement.addEventListener('mouseenter', function(evt) {
      if (sorting) {
        // Here is where you change the styling of targetElement
        targetElement.style.backgroundColor = 'red';
      }
    });
    
    targetElement.addEventListener('mouseleave', function(evt) {
      if (sorting) {
        // Here is where you remove the styling of targetElement
        targetElement.style.backgroundColor = '';
      }
    });
    
    el.addEventListener('touchmove', function(evt) {
      if (!sorting) { return; }
      var x = evt.touches[0].clientX;
      var y = evt.touches[0].clientY;
      var elementAtTouchPoint = document.elementFromPoint(x, y);
      if (elementAtTouchPoint === targetElement ||
          // In case of a ghost element, the element at touch point
          // is the ghost element and thus we need to check if the parent 
          // of the ghost element is the targetElement.
          elementAtTouchPoint.parentNode === targetElement) {
        targetElement.style.backgroundColor = 'red';
      } else {
        // Here is where you remove the styling of targetElement
        targetElement.style.backgroundColor = '';
      }
    });
    

    Basically, if Sorting with SortableJS, you do mouseenter & mouseleave events for the fallback, and dragenter & dragleave events (ignore bubbles) for native drag&drop. You will want both if you do not have forceFallback: true.