如何在Jquery Sortable插件中实现自动垂直滚动?

3

我正在使用Jquery-Sortable插件(链接)来构建我的菜单项目的拖放功能,就像这里所示,只是在wordpress menubuilder中。

包含所有菜单项的容器高度是固定的,因此当菜单项的数量超过容器高度时,很难将顶部项拖到容器底部。

$(function() {
  $("ol.default").sortable({
    group: 'item'
  });
})
body.dragging,
body.dragging * {
  cursor: move !important;
}

.overflow {
  height: 200px;
  overflow-x: hidden;
  overflow-y: auto;
  margin-top: 20px;
}

.dragged {
  position: absolute;
  top: 0;
  opacity: 0.5;
  z-index: 2000;
}


/* line 10, jquery-sortable.css.sass */

ol.vertical {
  margin: 0 0 9px 0;
}


/* line 12, jquery-sortable.css.sass */

ol.vertical li {
  display: block;
  margin: 5px;
  padding: 5px;
  border: 1px solid #cccccc;
  color: #0088cc;
  background: #eeeeee;
}

ol.vertical li.placeholder {
  position: relative;
  margin: 0;
  padding: 0;
  border: none;
}

ol.vertical li.placeholder:before {
  position: absolute;
  content: "";
  width: 0;
  height: 0;
  margin-top: -5px;
  left: -5px;
  top: -4px;
  border: 5px solid transparent;
  border-left-color: red;
  border-right: none;
}

ol {
  list-style-type: none;
}

ol i.icon-move {
  cursor: pointer;
}

ol li.highlight {
  background: #333333;
  color: #999999;
}

ol li.highlight i.icon-move {
  background-image: url("../img/glyphicons-halflings-white.png");
}

ol.nested_with_switch,
ol.nested_with_switch ol {
  border: 1px solid #eeeeee;
}

ol.nested_with_switch.active,
ol.nested_with_switch ol.active {
  border: 1px solid #333333;
}

ol.nested_with_switch li,
ol.simple_with_animation li,
ol.default li {
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<script src="https://johnny.github.io/jquery-sortable/js/jquery-sortable-min.js"></script>


<div class="overflow">
  <ol class="default vertical">
    <li>elem1</li>
    <li>elem2</li>
    <li>elem3</li>
    <li>elem4</li>
    <li>elem5</li>
    <li>elem6</li>
    <li>elem7</li>
    <li>elem8</li>
    <li>elem9</li>
    <li>elem10</li>
  </ol>
</div>

<div class="overflow">
  <ol class="default vertical">
    <li>elem1</li>
    <li>elem2</li>
    <li>elem3</li>
    <li>elem4</li>
    <li>elem5</li>
    <li>elem6</li>
    <li>elem7</li>
    <li>elem8</li>
    <li>elem9</li>
    <li>elem10</li>
  </ol>
</div>

我试图寻找自动滚动的解决方案,但似乎并没有多少关于这个问题的提及。虽然插件 GitHub 中提到了此问题,但在我的情况下似乎不起作用。请问应该如何解决?请帮忙,谢谢。
2个回答

1

您需要使用正确的jQuery UI版本,请尝试以下代码段

$("ol.default").sortable({
  onDrag: (item, position, sup, event) => {
    const container = $(item).parents('.overflow');
    const containerTop = container.offset().top;
    const containerBottom = containerTop + container.height();

    if (event.pageY > containerBottom) {
      container.scrollTop(container.scrollTop() + 10);
    } else if (event.pageY < containerTop) {
      container.scrollTop(container.scrollTop() - 10);
    }
  }
})
body.dragging,
body.dragging * {
  cursor: move !important;
}

.overflow {
  height: 200px;
  overflow-x: hidden;
  overflow-y: auto;
  margin-top: 20px;
}

.dragged {
  position: absolute;
  top: 0;
  opacity: 0.5;
  z-index: 2000;
}


/* line 10, jquery-sortable.css.sass */

ol.vertical {
  margin: 0 0 9px 0;
}


/* line 12, jquery-sortable.css.sass */

ol.vertical li {
  display: block;
  margin: 5px;
  padding: 5px;
  border: 1px solid #cccccc;
  color: #0088cc;
  background: #eeeeee;
}

ol.vertical li.placeholder {
  position: relative;
  margin: 0;
  padding: 0;
  border: none;
}

ol.vertical li.placeholder:before {
  position: absolute;
  content: "";
  width: 0;
  height: 0;
  margin-top: -5px;
  left: -5px;
  top: -4px;
  border: 5px solid transparent;
  border-left-color: red;
  border-right: none;
}

ol {
  list-style-type: none;
}

ol i.icon-move {
  cursor: pointer;
}

ol li.highlight {
  background: #333333;
  color: #999999;
}

ol li.highlight i.icon-move {
  background-image: url("../img/glyphicons-halflings-white.png");
}

ol.nested_with_switch,
ol.nested_with_switch ol {
  border: 1px solid #eeeeee;
}

ol.nested_with_switch.active,
ol.nested_with_switch ol.active {
  border: 1px solid #333333;
}

ol.nested_with_switch li,
ol.simple_with_animation li,
ol.default li {
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<script src="https://johnny.github.io/jquery-sortable/js/jquery-sortable-min.js"></script>


<div class="overflow">
  <ol class="default vertical">
    <li>elem1</li>
    <li>elem2</li>
    <li>elem3</li>
    <li>elem4</li>
    <li>elem5</li>
    <li>elem6</li>
    <li>elem7</li>
    <li>elem8</li>
    <li>elem9</li>
    <li>elem10</li>
  </ol>
</div>

<div class="overflow">
  <ol class="default vertical">
    <li>elem1</li>
    <li>elem2</li>
    <li>elem3</li>
    <li>elem4</li>
    <li>elem5</li>
    <li>elem6</li>
    <li>elem7</li>
    <li>elem8</li>
    <li>elem9</li>
    <li>elem10</li>
  </ol>
</div>


谢谢。它适用于jquery-ui,但是我的当前项目已经全部使用了这个https://johnny.github.io/jquery-sortable/的jquery sortable库进行了适应。我无法改变我的当前项目以适应jquery-ui小部件,因为这需要大量的工作来更改。 - Houy Narun
现在试试吧,我已经更新了代码片段以使用之前的库。 - Shridhar Sharma
现在滚动条跟随鼠标拖动是可以的,但是当我将拖动的项目移动到非常顶部或底部时,有时候它并不会跟随。谢谢。 - Houy Narun
很遗憾,如果不更改库内部的代码,就无法实现该功能,因为该库没有提供任何手动重置指针的方法。 - Shridhar Sharma
引用作者的话:“你应该能够在不篡改源代码的情况下获得所需的行为。” https://github.com/johnny/jquery-sortable/issues/46 - Houy Narun
这并没有帮助。 - Shridhar Sharma

0

style.css

body.dragging,
            body.dragging * {
              cursor: move !important;
            }

            .overflow {
              height: 200px;
              overflow-x: hidden;
              overflow-y: auto;
              margin-top: 20px;
            }

            .dragged {
              position: absolute;
              top: 0;
              opacity: 0.5;
              z-index: 2000;
            }


            /* line 10, jquery-sortable.css.sass */

            ol.vertical {
              margin: 0 0 9px 0;
            }


            /* line 12, jquery-sortable.css.sass */

            ol.vertical li {
              display: block;
              margin: 5px;
              padding: 5px;
              border: 1px solid #cccccc;
              color: #0088cc;
              background: #eeeeee;
            }

            ol.vertical li.placeholder {
              position: relative;
              margin: 0;
              padding: 0;
              border: none;
            }

            ol.vertical li.placeholder:before {
              position: absolute;
              content: "";
              width: 0;
              height: 0;
              margin-top: -5px;
              left: -5px;
              top: -4px;
              border: 5px solid transparent;
              border-left-color: red;
              border-right: none;
            }

            ol {
              list-style-type: none;
            }

            ol i.icon-move {
              cursor: pointer;
            }

            ol li.highlight {
              background: #333333;
              color: #999999;
            }

            ol li.highlight i.icon-move {
              background-image: url("../img/glyphicons-halflings-white.png");
            }

            ol.nested_with_switch,
            ol.nested_with_switch ol {
              border: 1px solid #eeeeee;
            }

            ol.nested_with_switch.active,
            ol.nested_with_switch ol.active {
              border: 1px solid #333333;
            }

            ol.nested_with_switch li,
            ol.simple_with_animation li,
            ol.default li {
              cursor: pointer;
            }

index.html

<!doctype html>
<html>
    <head>
        <title>Vertical Scroll in jquery vertical short</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://johnny.github.io/jquery-sortable/js/jquery-sortable-min.js"></script>
        <link rel="stylesheet" href="style.css"/>
        <script>
            (function(){
                $(function(){
                   $(function() {
                       window.posY = 0;
                       window.posX = 0;
                       window.dragStart = false;
                       window.dragCon_el = null;
                       window.dragCon_left = 0;
                       window.dragCon_top = 0;
                      $("ol.default").sortable({
                          pullPlaceholder: false,
                          vertical: true,
                          group: 'item',
                          onDrag: function($item, position, _super, event) {
                              if (window.dragStart && position.top >= window.dragCon_el.get(0).scrollTop + window.dragCon_el.height() + window.dragCon_top) {
                                      window.dragCon_el.get(0).scrollTo(
                                          window.dragCon_el.get(0).scrollLeft + ((position.left - posX) - (window.dragCon_left * 2)),
                                          window.dragCon_el.get(0).scrollTop + ((position.top - posY) - (window.dragCon_top * 2))
                                      );
                                   window.posX = event.pageX;
                                   window.posY = event.pageY;
                               }
                          },
                          onDragStart: function($item, container, _super, event) {
                              let $container = $item.closest('.overflow');
                              window.dragStart = true;
                              window.posY = event.pageY;
                              window.posX = event.pageX;
                              window.dragCon_el = $container;
                              window.dragCon_top = $container.offset().top;
                              window.dragCon_left = $container.offset().left;
                          },
                          onDrop: function($item, container, _super, event) {
                              window.dragStart = false;
                          }
                      });
                    }); 
                });
            })(jQuery)
        </script>
    </head>
    <body>
        <div class="overflow">
          <ol class="default vertical">
            <li>elem1</li>
            <li>elem2</li>
            <li>elem3</li>
            <li>elem4</li>
            <li>elem5</li>
            <li>elem6</li>
            <li>elem7</li>
            <li>elem8</li>
            <li>elem9</li>
            <li>elem10</li>
          </ol>
        </div>

        <div class="overflow">
          <ol class="default vertical">
            <li>elem1</li>
            <li>elem2</li>
            <li>elem3</li>
            <li>elem4</li>
            <li>elem5</li>
            <li>elem6</li>
            <li>elem7</li>
            <li>elem8</li>
            <li>elem9</li>
            <li>elem10</li>
          </ol>
        </div>
    </body>
</html>

我已经测试过了,它不能够顺畅地工作。当我将一个项目拖动到容器的底部时,滚动条会自动回到顶部。谢谢。 - Houy Narun
当我拖动并将项目移动到顶部时,它也无法工作。谢谢。 - Houy Narun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接