7

Я использую пользовательский интерфейс JQuery для реализации изменяемых размеров/перетаскиваемых элементов. Теперь я хотел бы определить ограничение для этих элементов, которое ограничивает изменение размера/перетаскивание на ровно три (!) Стороны. Например. посмотрите на это JSFiddle example. Вы можете видеть, что содержащийся элемент можно изменить или изменить только внутри родительской области.JQuery UI draggable: Превышение сдерживания на одной стороне

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

Так this modification то, что я придумал:

// resizable/draggable option 
resize/drag : function(event, ui) { 
    expandParent("#parentElement", "#dragElement"); 
} 

function expandParent(parentName, childName) { 
    var dragEl = $(childName); 
    var dragElTop = parseInt(dragEl.css("top"), 10); 
    var dragElHeight = parseInt(dragEl.css("height"), 10); 
    var dragElBottom = dragElTop + dragElHeight; 
    var parentEl = $(parentName); 
    var parentElBottom = parseInt(parentEl.css("height")); 
    if(parentElBottom <= dragElBottom + 20) { 
     parentEl.css("height", "+=2"); 
    } 
} 

Если вы поиграйте с нижней границей вы заметили, что область родителя расширяются, если ребенок получает слишком близко к нижней границе родителя. К сожалению, это останавливается после 20 пикселей. Затем вам нужно отпустить кнопку мыши и изменить размер/перетащить еще раз, чтобы расширить область дальше. У вас есть идея, почему это так?

+0

Без испытав код или что-нибудь , Я заметил следующую строку: 'if (parentElBottom <= dragElBottom + 20) {' может быть, что '20' вызывает проблему? –

+0

Ну, да, вы можете переместить элемент в самое низкое возможное положение, которое было частью родительской области в начале движения. Поэтому расширение области каким-то образом не перенаправляется на модель JQuery UI, я думаю. – Bastian

ответ

5

Хорошо, что функция expandParent не будет работать, поскольку границы контейнера установлены с помощью JQuery UI, и это не будет обновлено до тех пор, пока вы не отпустите мышь.

Так я могу думать о двух решения здесь один элегантный и другой хитрый

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

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

Вот мое решение:

<div id="parentElement"> 
    <div id="dummy-parent"> 
     <div id="dragElement" class="dragClass"> 
      <p>Drag me around!</p> 
     </div> 
    </div> 
</div> 



function expandParent(parentName, childName) { 
    var dragEl = $(childName); 
    var parentEl = $(parentName); 
    var dragElHeight=dragEl.height(); 
    if(parentEl.height() <= dragElHeight) { 
     parentEl.height(dragElHeight); 
    } 
} 

Check the JS Fiddle

Вы должны изменить код, основанный на приложении я просто дал вам идею

+0

Трудное решение кажется умным! Таким образом, нет возможности манипулировать значениями, которые использует пользовательский интерфейс JQuery? Я предполагаю, что они установлены в каком-то контейнере где-то, поэтому, возможно, можно действовать по этому поводу. – Bastian

+1

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

2

Похоже, что внутри пользовательского интерфейса JQuery они сохраняют информацию родителя в начале перетаскивания, поэтому даже если вы измените размер, он все равно будет ограничивать перетаскивание.

Чтобы исправить это, вы можете установить свой ограничивающий ограничитель.

$("#dragElement") 
    .draggable({ 
     cursor  : "move", 
     scroll  : false, 
     containment : [20, 20, 400+20, 1000], 
     drag : function(event, ui) { 
      expandParent("#parentElement", "#dragElement"); 
     } 
    }) 
    .resizable({ 
     containment : "parent", 
     resize : function(event, ui) { 
      expandParent("#parentElement", "#dragElement"); 
     } 
    }); 

function expandParent(parentName, childName) { 
    var dragEl = $(childName); 
    var dragElTop = parseInt(dragEl.css("top"), 10); 
    var dragElHeight = parseInt(dragEl.css("height"), 10); 
    var dragElBottom = dragElTop + dragElHeight; 
    var parentEl = $(parentName); 
    var parentElBottom = parseInt(parentEl.css("height")); 
    if(parentElBottom <= dragElBottom + 20) { 
     parentEl.css("height", dragElBottom+20); 
    } 
} 

Приведенный выше код позволит изменить размер родителя до 1000 + 20 в высоту. Вы можете попробовать вышеуказанный код here (JSFiddle).

Если необходимо сделать динамический контейнер в начале (и в методе изменения размера), установите новый контейнер с правильным BoundingBox.

var p = $("#parentElement"); 
var dragWidth = parseInt($("#dragElement").css('width')); 
var left = p[0].offsetLeft; 
var top = p[0].offsetTop; 
var width = parseInt(p.css("width"), 10)-dragWidth; 
var containment = [left, top, width+left, 1000]; 

Да, я знаю, решение вроде хака .. но в любом случае, я просто обновил JSFiddle Это решение не может быть, чтобы вычислить и повторно установить динамически размер контейнера. Просто хотел, чтобы JSFiddle работал красиво.

+0

Хорошо, это подход, о котором я еще не думал. Но он ограничен абсолютными значениями, не так ли? Я хотел бы, чтобы сдерживание было относительно родителя. Ручная адаптация положения ограничительной рамки к положению родителя кажется довольно неудобной и многословной. – Bastian

+0

Я добавил код, чтобы вычислить ограничительную рамку сдерживания. – wendelbsilva

+0

Я только что обновил [JSFiddle] (http://jsfiddle.net/74Sxn/), и решение работает корректно и динамично. Просто хотел иметь рабочую версию решения там. – wendelbsilva

0
$("#dragElement") 
     .draggable({ 
      cursor  : "move", 
      containment : '#Container', 
      drag : function(event, ui) { 
       var growAmount = 10; 
       var cont = $('#Container'); 
       var item = $(ui.helper); 

       var itemOffset = item.offset(); 
       itemOffset.bottom = itemOffset.top + dProps.item.height(); 


       var contOffset= cont.offset(); 
       contOffset.bottom = contOffset.top + cont.height(); 

       if(itemOffset.bottom >= contOffset.bottom){ 
        var inst = item.draggable("instance"); 
        inst.containment = [inst.containment[0], inst.containment[1], inst.containment[2], inst.containment[3] + growAmount]; 
        cont.height(parseInt(cont.height()) + growAmount); 
       } 
      } 
     });