传递/更改jQuery UI拖动事件

10

我希望用户能够左右拖动水平菜单栏。我知道有很多轮播和滑块库可以实现这种行为,但它们都不适合我的情况。

当用户拖动一个LI时,它能否将新的x偏移信息传递给第一个LI左边距?

我在这里试了一下:http://jsfiddle.net/n92ng9uz/

以上示例的主要问题在于,偏移仍然应用于单个LI,如果阻止事件向上冒泡,则拖动不再平滑。


你想要实现什么目标?如果你将可拖动属性设置在 UL 上而不是 LI 上会怎样呢?$('ul').draggable({ axis: 'x', drag: function(e, ui) { } }); - Trevor
我认为在走马灯/滑块中使用ul作为容器并应用white-space:nowrap的技术是很常见的,然后对第一个li应用负边距。如果你要将jQuery UI与之集成,它也必须遵循这个方法。这就是为什么我不能接受将ul拖动作为问题的答案。谢谢! - rob-gordon
4个回答

2
由于您在评论中指定了第一个
  • 元素必须使用margin-left,并且不修改
      的位置,我相信使用jQuery UI draggable不能轻松完成。如果我们使
    • 可拖动,我们将无法捕获其他
    • 上的鼠标事件;如果我们使
        可拖动,我们不能轻松地仅影响第一个
      • margin-left而不是
          的位置。

          这里是一个实时演示解决方案,直接使用鼠标事件,而不是使用jQuery UI:

          var firstLI = $('li:first-child');
          
          var initx = 0;
          var dragstartx = 0;
          var dragging = false;
          
          $("ul").mousedown(function(e) {
              dragging = true;
              dragstartx = e.pageX;
              initx = parseInt(firstLI.css("marginLeft"), 10);
          });
          
          $("ul").mousemove(function(e) {
              if (dragging) {
                  firstLI.css("marginLeft", (initx + e.pageX - dragstartx) + "px");
              }
          });
          
          $("ul").mouseleave(function(e) {
              dragging = false;
          });
          
          $("ul").mouseup(function(e) {
              dragging = false;
          });
          ul {
              list-style: none;
              margin: 0;
              padding: 0;
              overflow: hidden;
              white-space: nowrap;
              -webkit-touch-callout: none;
              -webkit-user-select: none;
              -khtml-user-select: none;
              -moz-user-select: none;
              -ms-user-select: none;
              user-select: none;
          }
          
          ul > li {
              display: inline-block;
              padding: 10px;
          }
          
          ul > li:nth-child(odd) {
              background: orangered;
          }
          
          ul > li:nth-child(even) {
              background: gold;
          }
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
          <ul>
              <li>Link 1</li>
              <li>Link 2</li>
              <li>Link 3</li>
              <li>Link 4</li>
              <li>Link 5</li>
              <li>Link 6</li>
              <li>Link 7</li>
              <li>Link 8</li>
              <li>Link 9</li>
              <li>Link 10</li>
          </ul>

          JSFiddle版本:https://jsfiddle.net/n92ng9uz/2/

          (此内容无需翻译)

  • 1

    编辑:算了...我自己解决了...你需要将每个项目向左移动位置差。我想这就是你想要的:http://jsfiddle.net/xwesf1Lt/。如果我错了,请告诉我。请注意,我已将diff变量更改为仅左侧位置。

    另外,我们不是修改边距,而是修改左属性。

    var firstLI = $('ul:first-child')[0];
    firstLI.style.marginLeft = 0;
    
    $('li').draggable({
        axis: 'x',
        drag: function(e, ui) {
            var diff = ui.position.left;
            console.log(diff);
            var currentLeft = parseInt(firstLI.style.marginLeft, 10);
            var offset = currentLeft + diff + 'px';
            //firstLI.style.marginLeft = diff;
            //  to drag all of them:
    
            $("li").each(function(index) {
                $(this).css("left", offset);
            });
    
            // with this enabled, can only be moved 1px at a time..?
            // e.preventDefault();
        }
    });
    

    这是一个不错的解决方案IAMZERG。所以我会点赞,因为它可能是正确的解决方案,适用于稍后挖掘问题的某个人。它只是不能满足第一个li margin-left的要求,所以我不能将其标记为正确答案。谢谢! - rob-gordon

    0

    这样行不行?将边距添加到 ul 中?在 fiddle 中似乎可以工作!

    var ul = $('ul');
    
    ul.draggable({
        axis: 'x',
        drag: function(e, ui) {
            ul.css({marginLeft: ui.position - ui.originalPosition});
        }
    });
    

    -1
    如果您希望用户能够自由拖动导航栏并且它应该在同一位置落下,那么您可以尝试使用jQuery dad插件。由于代码的简单性,这是我使用过的最好的拖放插件。
    如果您愿意,请点击此处查看其演示和文档。

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