2017-02-13 4 views
0

So verwende ich jquery-ui sortierbar in einem flexiblen Layout, um ein Raster zu erstellen, das durch Ziehen und Ablegen neu angeordnet werden kann.Jquery Platzhalter ungenau

In den meisten Fällen, wenn der Cursor zuletzt nach unten bewegt wurde, erscheint der Platzhalter auf der rechten Seite und wenn der Cursor zuletzt nach oben bewegt wurde, erscheint der Platzhalter auf der linken Seite.

Was ich will, ist der Platzhalter in der Lücke am nächsten sein, wo der Cursor ist.

Hier ist eine vereinfachte Version von dem, was ich habe.

$('#sortable').sortable({ 
 
    placeholder: 'placeholder', 
 
    helper: 'clone', 
 
    tolerance: 'pointer', 
 
    start: function(event, ui) { 
 
    ui.item.show(); 
 
    $('.block-totara-featured-links-layout').sortable('option', 'cursorAt', { 
 
     left: ui.item.width()/2, 
 
     top: ui.item.height()/2 
 
    }); 
 
    } 
 
});
#sortable{ 
 
    width: 500px; 
 
    display: flex; 
 
    flex-wrap: wrap; 
 
} 
 
#sortable div { 
 
    margin: 10px; 
 
    background-color: #f00; 
 
    flex-basis: 100px; 
 
    height: 100px; 
 
    } 
 
#sortable div.placeholder { 
 
    max-width: 4px; 
 
    margin-left: -2px; 
 
    margin-right: -2px; 
 
    background-color: #00F; 
 
}
<script src="https://code.jquery.com/jquery-1.12.4.js"></script> 
 
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> 
 
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> 
 
<div id="sortable"> 
 
    <div>1</div> 
 
    <div>2</div> 
 
    <div>3</div> 
 
    <div>4</div> 
 
    <div>5</div> 
 
    <div>6</div> 
 
    <div>7</div> 
 
    <div>8</div> 
 
    <div>9</div> 
 
    <div>10</div> 
 
    <div>11</div> 
 
</div>

Antwort

0

So fixiert ich es durch das sortierbare Widget erstreckt und einige der Methoden, Hacking zu erkennen, ob der Zeiger auf der linken oder rechten eines Elements ist.

Ill Post hier den Code, damit die Menschen eine Vorstellung davon bekommen, was ich tat

$.widget('custom.sortableGrid', $.ui.sortable, { // A Hack of the base code so it puts the place holder in the right place 
 
     _onRightSide: function(item, event){ 
 
      return this._isOverAxis(
 
       event.pageX, 
 
       item.left + (item.width/2), 
 
       item.width/2 
 
      ); 
 
     }, 
 
     _intersectsWithPointer: function(item) { 
 
      var verticalDirection, horizontalDirection, 
 
       isOverElementHeight = (this.options.axis === "x") || 
 
        this._isOverAxis(
 
         this.positionAbs.top + this.offset.click.top, item.top, item.height), 
 
       isOverElementWidth = (this.options.axis === "y") || 
 
        this._isOverAxis(
 
         this.positionAbs.left + this.offset.click.left, item.left, item.width), 
 
       isOverElement = isOverElementHeight && isOverElementWidth; 
 

 
      if (!isOverElement) { 
 
       return false; 
 
      } 
 

 
      verticalDirection = this._getDragVerticalDirection(); 
 
      horizontalDirection = this._getDragHorizontalDirection(); 
 

 
      return (horizontalDirection === "right" || verticalDirection === "down") ? 2 : 1; 
 

 
     }, 
 
     _mouseDrag: function(event) { 
 
      var i, item, itemElement, intersection, 
 
       o = this.options, 
 
       scrolled = false; 
 

 
      //Compute the helpers position 
 
      this.position = this._generatePosition(event); 
 
      this.positionAbs = this._convertPositionTo("absolute"); 
 

 
      if (!this.lastPositionAbs) { 
 
       this.lastPositionAbs = this.positionAbs; 
 
      } 
 

 
      //Do scrolling 
 
      if (this.options.scroll) { 
 
       if (this.scrollParent[ 0 ] !== this.document[ 0 ] && 
 
        this.scrollParent[ 0 ].tagName !== "HTML") { 
 

 
        if ((this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight) - 
 
         event.pageY < o.scrollSensitivity) { 
 
         this.scrollParent[ 0 ].scrollTop = 
 
          scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed; 
 
        } else if (event.pageY - this.overflowOffset.top < o.scrollSensitivity) { 
 
         this.scrollParent[ 0 ].scrollTop = 
 
          scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed; 
 
        } 
 

 
        if ((this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth) - 
 
         event.pageX < o.scrollSensitivity) { 
 
         this.scrollParent[ 0 ].scrollLeft = scrolled = 
 
          this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed; 
 
        } else if (event.pageX - this.overflowOffset.left < o.scrollSensitivity) { 
 
         this.scrollParent[ 0 ].scrollLeft = scrolled = 
 
          this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed; 
 
        } 
 

 
       } else { 
 

 
        if (event.pageY - this.document.scrollTop() < o.scrollSensitivity) { 
 
         scrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed); 
 
        } else if (this.window.height() - (event.pageY - this.document.scrollTop()) < 
 
         o.scrollSensitivity) { 
 
         scrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed); 
 
        } 
 

 
        if (event.pageX - this.document.scrollLeft() < o.scrollSensitivity) { 
 
         scrolled = this.document.scrollLeft(
 
          this.document.scrollLeft() - o.scrollSpeed 
 
         ); 
 
        } else if (this.window.width() - (event.pageX - this.document.scrollLeft()) < 
 
         o.scrollSensitivity) { 
 
         scrolled = this.document.scrollLeft(
 
          this.document.scrollLeft() + o.scrollSpeed 
 
         ); 
 
        } 
 

 
       } 
 

 
       if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) { 
 
        $.ui.ddmanager.prepareOffsets(this, event); 
 
       } 
 
      } 
 

 
      //Regenerate the absolute position used for position checks 
 
      this.positionAbs = this._convertPositionTo("absolute"); 
 

 
      //Set the helper position 
 
      if (!this.options.axis || this.options.axis !== "y") { 
 
       this.helper[ 0 ].style.left = this.position.left + "px"; 
 
      } 
 
      if (!this.options.axis || this.options.axis !== "x") { 
 
       this.helper[ 0 ].style.top = this.position.top + "px"; 
 
      } 
 

 
      //Rearrange 
 
      for (i = this.items.length - 1; i >= 0; i--) { 
 

 

 
       //Cache variables and intersection, continue if no intersection 
 
       item = this.items[ i ]; 
 
       itemElement = item.item[ 0 ]; 
 
       intersection = this._intersectsWithPointer(item); 
 
       if (!intersection) { 
 
        continue; 
 
       } 
 

 
       this.direction = this._onRightSide(item, event) === true ? "right" : "left"; 
 
       this._rearrange(event, item); 
 

 

 
       if (!this._intersectsWithSides(item)) { 
 
        break; 
 
       } 
 

 
       this._trigger("change", event, this._uiHash()); 
 
       break; 
 
      } 
 

 
      //Post events to containers 
 
      this._contactContainers(event); 
 

 
      //Interconnect with droppables 
 
      if ($.ui.ddmanager) { 
 
       $.ui.ddmanager.drag(this, event); 
 
      } 
 

 
      //Call callbacks 
 
      this._trigger("sort", event, this._uiHash()); 
 

 
      this.lastPositionAbs = this.positionAbs; 
 
      return false; 
 

 
     }, 
 
     _rearrange: function(event, i, a, hardRefresh) { 
 
      a ? a[ 0 ].appendChild(this.placeholder[ 0 ]) : 
 
       i.item[ 0 ].parentNode.insertBefore(
 
        this.placeholder[ 0 ], 
 
        (this.direction === "left" ? i.item[ 0 ] : i.item[ 0 ].nextSibling) 
 
       ); 
 

 
      //Various things done here to improve the performance: 
 
      // 1. we create a setTimeout, that calls refreshPositions 
 
      // 2. on the instance, we have a counter variable, that get's higher after every append 
 
      // 3. on the local scope, we copy the counter variable, and check in the timeout, 
 
      // if it's still the same 
 
      // 4. this lets only the last addition to the timeout stack through 
 
      this.counter = this.counter ? ++this.counter : 1; 
 
      var counter = this.counter; 
 

 
      this._delay(function() { 
 
       if (counter === this.counter) { 
 

 
        //Precompute after each DOM insertion, NOT on mousemove 
 
        this.refreshPositions(!hardRefresh); 
 
       } 
 
      }); 
 

 
     } 
 
    });