【问题标题】:Dragging A Child Out Of A Container With Overflow-y:scroll使用溢出-y:滚动将孩子拖出容器
【发布时间】:2015-04-01 22:18:25
【问题描述】:

我有一个容器,里面有一个列表。列表项可以拖动,用鼠标移动。

容器可以滚动:

overflow-y: scroll;

通过设置此属性,Chrome 会自动将 overflow-x 属性设置为“自动”。如果我设置 overflow-x: visible 它会被 Chrome 忽略。如果我设置overflow-x: hidden,那么显然该项目被裁剪了。

当我将列表项拖到容器的左边缘或上边缘之外时,它会被裁剪到容器的边缘。如果我将它拖出右侧或底部边缘,容器会滚动以容纳它。我希望该项目能够拖到容器外而不会被裁剪并且不会触发滚动。

鉴于容器必须设置为overflow-y: scroll,而这反过来又会迫使 Chrome 设置overflow-x: auto,有什么办法可以实现还是不可能?

Codepen:http://codepen.io/Pedr/pen/azLWeY

注意:我知道我可以通过使用填充来偏移容器来解决这个问题(这样容器的限制实际上会超出其视觉边缘),但在我的情况下这不是一个选项.

$(function() {
  $('.Wrapper').mousemove(function(event){
    $('.Item').offset({left: event.pageX, top: event.pageY});
  });
})
html,
body {
  height: 100%;
}

.Wrapper {
  width: 100%;
  height: 100%;
  position: absolute;
}

.Container {
  background: grey;
  position: absolute;
  width: 50%;
  left: 25%;
  min-height: 100%;
  overflow-y: scroll;
  overflow-x: hidden; // Clips Item
  // If left at auto it will clip the item on the top and left edge and scroll if the item overlaps the bottom or right edge.
}

.Item {
  padding: 20px;
  background: red;
  position: absolute;
  width: 600px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="Wrapper">
  <div class="Container">
    <div class="Item">ITEM</div>
  </div>
</div>

【问题讨论】:

  • 哈哈,这个标题引起了我的注意! “将孩子从容器中拖出”......什么?哦,那个……
  • 郑重声明,我认为您不应该对所有不是您想要的答案投反对票。
  • @deebs 我只是对每一个花费零努力编写的答案投了反对票。
  • 如果有答案,那么“零努力”是不可能的。我想你可以说“最小的努力”......这更容易理解。无论哪种方式,您可以确定每个人所做的努力这一事实非常了不起。
  • @deeps 我一定让你很不高兴,因为你一天后回来编辑你的评论。这不是人气竞赛。如果答案显示出很少的努力(并且我认为用 JS 解决这样的 CSS 问题需要很少的努力)或者没有以我满意的方式解决问题,那么我将其标记为因为我没有考虑过有用。

标签: html css drag-and-drop overflow clip


【解决方案1】:

ITEM 设置为固定位置....以将其从其他位置移开

它的工作原理像这样

$(function() {
  $('.Wrapper').mousemove(function(event){
      $('.Item').css('position', 'fixed');
      $('.Item').offset({left: event.pageX, top: event.pageY});
    });
})

看这里的sn-p:

$(function() {
  $('.Wrapper').mousemove(function(event){
      $('.Item').css('position', 'fixed');
      $('.Item').offset({left: event.pageX, top: event.pageY});
    });
})
.Wrapper {
  width: 100%;
  height: 100%;
  position: absolute;
}

.Container {
  background: grey;
  position: absolute;
  width: 50%;
  left: 25%;
  min-height: 100%;
  overflow-y: scroll;
  overflow-x: hidden; // Clips Item
  // If left at auto it will clip the item on the top and left edge and scroll if the item overlaps the bottom or right edge.
}

.Item {
  padding: 20px;
  background: red;
  position: absolute;
  width: 600px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="Wrapper">
  <div class="Container">
    <div class="Item">ITEM</div>
  </div>
</div>

【讨论】:

    【解决方案2】:

    这是我的编辑:http://codepen.io/anon/pen/MYrxGJ

    我所做的是,将Wrapper的位置设置为相对,删除Container的位置CSS,并将其设置为margin-left: 25%; margin-right: 25%;(效果与margin: 0px auto;相同)。这样Item div的绝对定位是相对于Wrapper div,而不是Container div。

    【讨论】:

      【解决方案3】:

      我个人会使用position:fixed - 它会将可拖动对象从容器的渲染树中拉出,因此就容器而言,它与溢出无关,只会直接在容器上绘制没有任何滚动条或剪辑的窗口。

      $('.Wrapper').on("mousedown", ".Item", function(event){
          $(event.target)
              .css('position', 'fixed')
              .on("mousemove", function(event){
                  // Take into account offset within element
                  $(this).offset({left: event.pageX, top: event.pageY});
              })
              .one("mouseup", function(event){
                  // Finish dealing with element and clear position and event
                  $(this)
                      .off("mousemove")
                      .css('position', '');
              })
      });
      

      【讨论】:

        【解决方案4】:

        我相信这可以解决您的溢出问题。基本上,在 .mousemove() 上“关闭”溢出-y 并最初将 item 元素设置在容器之外。你可以从容器中删除 position: absolute ,并拥有这个:http://codepen.io/anon/pen/jEaRaz

        $(function() {
          $('.Wrapper').mousemove(function(event){
          $('.Item').offset({left: event.pageX, top: event.pageY});
          $('.Container').css('overflow-y', 'hidden')
          });
        })
        

        【讨论】:

          【解决方案5】:

          您可以在选择项目时将项目复制到容器之外,然后在删除后将其删除。

          http://codepen.io/anon/pen/OPOMMp

          另外,我会在包装器上隐藏溢出。

          .Wrapper {
            width: 100%;
            height: 100%;
            position: absolute;
            overflow: hidden;
          }
          

          【讨论】:

          • 虽然这可以解决问题,但也可以避免它。不幸的是,我受到 JS 组件的限制,该组件不允许拖动的项目存在于原始容器之外。
          【解决方案6】:

          我认为这可以通过简单地将大部分元素设置在布局中并将可拖动项目设置为“布局外”来完成,事实证明我是正确的。如果您从包装器和容器中删除 position: absolute(使它们在布局中呈现),然后给容器 margin-left: 25%,您将保持与以前相同的效果,但是,因为项目本身是位置: absolute 没有相对或绝对定位的父元素,它被定位为“布局外”,这意味着它可以从该容器中出来。看这个例子:http://codepen.io/anon/pen/vEWGaa

          (所以希望我有一些带有 codepen 链接的代码,所以这是新的 CSS):

          html,
          body {
            height: 100%;
          }
          
          .Wrapper {
            width: 100%;
            height: 100%;
          }
          
          .Container {
            background: grey;
            width: 50%;
            margin-left: 25%;
            min-height: 100%;
            overflow-y: scroll;
            overflow-x: hidden; // Clips Item
            // If left at auto it will clip the item on the top and left edge and scroll if the item overlaps the bottom or right edge.
          }
          
          .Item {
            padding: 20px;
            background: red;
            position: absolute;
            width: 600px;
          }
          

          编辑:此外,如果您将溢出:隐藏在主体上,当您的项目被拖动到屏幕外时,您将不会获得滚动条。

          【讨论】:

            【解决方案7】:

            试试这个方法,我已经克隆了可拖动项并附加到正文。

            JS

            var cloneItem = $('.Item').clone().hide().appendTo("body");
            

            http://codepen.io/nandhakumaru/pen/VYyMqr

            【讨论】:

              猜你喜欢
              • 2019-08-04
              • 1970-01-01
              • 2017-03-02
              • 2020-11-19
              • 2011-08-16
              • 2016-11-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多