JQuery UI draggable: превысьте сдерживание на одной стороне

Я использую jQuery UI для реализации изменяемых / перетаскиваемых элементов. Теперь я хотел бы определить сдерживание для этих элементов, которое ограничивает изменение размера / перетаскивание ровно трех(!) стороны. Е. Г. взгляните на это пример JSFiddle. Вы можете видеть, что содержащийся элемент может быть изменен / перетащен только в область родителя.

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

Так эта модификация - это то, что я придумал:

// 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 пикселей. Затем нужно отпустить кнопку мыши и измените размер / перетащите еще раз, чтобы расширить область. Ты хоть представляешь, почему?

3 ответов


Ну, что функция 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);
    }
}

Проверьте скрипку JS

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


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

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

$("#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 в высоту. Вы можете попробовать приведенный выше код здесь (JSFiddle).

Если нужно сделать динамический контейнер, в начале (и в метод resize), установите новый контейнер с правильным 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 работал хорошо.


    $("#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);
                }
            }
        });