jQuery UI issue, droppable and overflow scroll

2019-09-19 12:55发布

问题:

I used the search and have not found an answer to my problem even if I've seen the same problem on other issues. I need that ".draggable" scroll '#div1' when you introduce the element. I put the jsFiddle: http://jsfiddle.net/carlosnufe/7Rxst/

jQuery:

$('.draggable').draggable({
    appendto : "#div1",
    helper  : "clone"
})
$('#div1').droppable({
    scroll: true,
});

HTML:

<div id="div1">
    <div class="demo"></div>
    <div class="demo"></div>
    <div class="demo"></div>
    <div class="demo"></div>
    <div class="demo"></div>
    <div class="demo"></div>
    <div class="demo"></div>
    <div class="demo"></div>
    <div class="demo"></div>
  </div>

  <div id="div2">
    <div class="draggable"></div>
  </div>

回答1:

There are a couple of mistakes in your code:

appendto : "#div1", // I assume this is a typo of "appendTo"
// ...
scroll: true, // AFAIK there is no option called "scroll" on a droppable

Now, from what I understand what you're trying to do is to make the .droppable() scroll to some predefined position when it accepts a .draggable(). The "accept a draggable" event in a droppable is actually called drop:

$("#div1").droppable({
    drop: function() {
        // myPosition can be this.height if you want to scroll all the way down
        $(this).scrollTop(myPosition);
    }
});

(there is also an accept option, but using it in such a way would be abusing its purpose)

I've put this in your fiddle here as a demo. I've also made a few other tweaks, so you can actually see it working (note that you can't have regular divs on top of position:relative;float:left; elements, thus I'm also adding the .demo class to them)


In the case where you want the .demo-s to accept the drops, you don't want to make the whole container #div1 a droppable element. What you can do, is manipulate its .scrollTop value whenever you fulfill certain conditions while dragging your draggable element.

You can do this with either the drag event on the draggable or over event on the droppable. It's a matter of preference, as both are rather expensive, but I'd prefer going with the second one:

$('.demo').droppable({
    over: function(e, ui) {
        if(conditionForScrollingUp) {
            // scroll container up
            $("#div1").scrollTop($("#div1").scrollTop() - magicNumber);
        } else if(conditionForScrollingDown) {
            // scroll container down
            $("#div1").scrollTop($("#div1").scrollTop() + magicNumber);
        }
    }
});

This will unfortunately slow down your page quite a bit, especially if you have a large number of div.demo-s.

Here's another fiddle showing this working with your example. To get it to scroll, drag the draggable objects over the top or bottom of the #div1 container.

A further extension you might want to do is to get it to scroll smoothly while your mouse pointer is standing still. You can do this with some creative use of setTimeout or setInterval; I won't go into detail on this, as you can find good explanations in either of these questions: jQuery open div on hover; automatic scroll through and Scroll on hover, click for speed