2017-02-13 10 views
0

Поэтому я использую jquery-ui sortable на гибком макете, чтобы создать сетку, которую можно переупорядочить путем перетаскивания.JQuery Placeholder Inaccurate

Что происходит большую часть времени, когда курсор двигался вниз, последнее место появляется справа, а когда курсор перемещается вверх, последний появляется слева.

Я хочу, чтобы заполнитель находился в промежутке, ближайшем к тому месту, где находится курсор.

Вот упрощенная версия того, что у меня есть.

$('#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>

ответ

0

Так что я установил его, расширяя Сортируемый виджет и взломе некоторые из способов распознать ли указатель находится на левой или правой части элемента.

Ill разместить код здесь, чтобы люди могли получить представление о том, что я сделал

$.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); 
 
       } 
 
      }); 
 

 
     } 
 
    });

 Смежные вопросы

  • Нет связанных вопросов^_^