两个区域的垂直可拖动分割线

14

我想制作一个垂直可拖动的两个区域的分割线,如下图所示。

enter image description hereenter image description here

我只是想修改一个可拖动 在线示例 以满足我的需求。最终,我得到了 这个。有人能给我一些修改的提示吗?


JSFiddle 链接:https://jsfiddle.net/casperhongkong/omekvtka/14/


HTML

<div class="container">
  <div class="area1">
Area 1
  </div>
  <div class="drag">

  </div>
  <div class="area2">
Area 2
  </div>
</div>

CSS

.container {
  position: fixed;
  top: 51px;
  right: 0px;
  bottom: 0px;
  left: 0px;
  background-color: #272822;
  border: 1px solid #222;
 // margin: 0 auto;
  //display: inline-block;
}

.area1 {
  position: absolute;
  height: 100%;
  width: 30%;
  background-color: #ddd;
  display: inline-block;
}

.drag {
  position: fixed;

  width: 5px;
  height: 100%;
  background-color: #444;
  display: inline-block;
}

.area2 {
  position: absolute;
  right: 0;
  height: 100%;
  width: 30%;
  background-color: #ddd;
  display: inline-block;
}

JavaScript

$(document).ready(function() {

  $('.drag').on('mousedown', function(e) {
    var $area1 = $('.area1'),
        $area2 = $('.area2'),
        startWidth_a1 = $area1.width(),
        startWidth_a2 = $area2.width(),
        pX = e.pageX;

    $(document).on('mouseup', function(e) {
      $(document).off('mouseup').off('mousemove');
    });

    $(document).on('mousemove', function(me) {
      var mx = (me.pageX - pX);
      $area1.css({
        width: startWidth_a1 - mx;
      });
      $area2.css({
        //left: mx / 2,
        width: startWidth_a2 - mx,
        //top: my
      });
    });

  });
});

6
我强烈推荐使用split.js来实现此功能。https://nathancahill.github.io/Split.js/ - Donnie D'Amato
2
链接到split.js已经失效了。现在它是https://split.js.org。 - Danil Pyatnitsev
2个回答

5

对于JavaScript,我建议查看一个库,因为这比仅仅几行代码要复杂一些。@fauxserious提供了Split.js作为一个很好的例子。

虽然有些受限,但在纯HTML/CSS中也是可能实现的,正如这里所讨论的那样。

HTML:

<div class="split-view">
    <div class="resize-x panel" style="width: 216px;">
      Panel A
    </div>
    <div class="panel">
      Panel B
    </div>
</div>

CSS:

/* Panels: */
.panel{ 
    padding: 1em; 
    border-width: 6px; 
    border-style: solid; 
    height: 4em; 
}

/* Resizing */
.resize-x { 
    resize: horizontal;
    overflow: auto;
}

/* Split View */
.split-view {
    margin: 1em 0; 
    width: 100%;
    clear: both;
    display: table;
}

.split-view .panel {
    display: table-cell;
}

1
拖动区域太小了,能不能变大一点? - Casper

0

基于@afischer的表格单元解决方案,这里提供另一种替代方案。
我必须在左侧面板中放置手风琴。

手风琴的粘性标题需要overflow可见,
而调整大小需要overflow除了可见之外的任何值:
https://caniuse.com/#feat=css-sticky

同时,我不需要在右侧面板中放置任何内容。

因此,一个解决方法是在右侧面板上使用resize,并将其旋转180度以使可拖动的一侧位于中间,这样可拖动的角落就被重新定位到顶部(无需滚动即可看到)。

此外,还添加了一些突出显示的可拖动角落。

/* Panels: */
.panel{ 
  padding: 1em; 
  border-width: 6px; 
  border-style: solid; 
  height: 4em; 
}

/* Resizing */
.resize-x { 
  resize: horizontal;
  overflow: auto;
  transform: rotate(180deg);
  border-right: solid gray 1px;
}

/* Split View */
.split-view {
  margin: 1em 0; 
  width: 100%;
  clear: both;
  display: table;
}

.split-view .panel {
  display: table-cell;
}

.resize-x::-webkit-resizer {
    border-width: 8px;
    border-style: solid;
    border-color: transparent orangered orangered transparent;
  }
<div class="split-view">
    <div
      class="panel"
      style="width: 216px;">
        Panel A
    </div>
    <div class="panel resize-x">
      Panel B
    </div>
</div>

不幸的是,上述方法有两个令人失望的问题:

  • Firefox无法处理table-cell和resize的组合
  • 只有抓手的一个角落是响应的,甚至可以轻松地滚动出去

这里有另一种解决方案,也考虑了以上两个问题

  • 没有resize CSS属性
  • 并且具有完整高度响应式抓手

它是flexbox和input:range滑块的组合。

诀窍在于pointer-event CSS属性可以不同

  • 在滑块的背景上
  • 以及在其抓手上。

滑块覆盖整个视图。滑块的背景对事件也是透明的(pointer-events:none),而拖动条本身捕获事件(pointer-events:auto)。

它需要少量的Javascript,并且因为我已经在Nuxt.js中实现了生产版本,所以我在这里使用Vue.js,而不是vanilla JS。

new Vue({
        el: '#vue',

        data: {
          windowWidth: null,
          splitWidth: null,
        },

        mounted() {
          this.windowWidth = window.innerWidth;
          // For arbitrary initial position:
          this.splitWidth = this.windowWidth * 2/3;
        },

        computed: {
          flexRatio() {
            return this.splitWidth / this.windowWidth;
          }
        }

      })
body {
        margin:0;
      }

      main {
        display: flex;
        width: 100%;
        height: 100vh;
      }

      article {
        display: flex;
      }

      section {
        width: 100%;
        height: 100%;
        text-align: justify;
        padding: 20px;
      }

      .section-left {
        background-color: darkseagreen;
      }

      .section-right {
        background-color: orangered;
      }

      #split-grabber {
        pointer-events: none;
        position: fixed;
        top: 0; right: 0; bottom: 0; left: 0;
        -webkit-appearance: none;
      /* Safari allows dragging behind scroll bar.
        We fix it by shrinking its width on the right side via both
        its range value      :max="windowWidth - 12"
        and its width (CSS)   width: calc(100% - 12px)
        ...synchronously  */
        width: calc(100% - 12px);
        height: 100vh;
        background: transparent;
        outline: none;
        margin: 0;
      }

      #split-grabber::-webkit-slider-thumb {
        z-index: 1;
        pointer-events: auto;
        -webkit-appearance: none;
        appearance: none;
        width: 5px;
        height: 100vh;
        background: lightgray;
        box-shadow: 1px 2px 2px 0px gray;
        cursor: col-resize;
      }

      #split-grabber::-moz-range-thumb {
        z-index: 1;
        pointer-events: auto;
        -webkit-appearance: none;
        appearance: none;
        width: 5px;
        height: 100vh;
        background: lightgray;
        box-shadow: 1px 2px 2px 0px gray;
        cursor: col-resize;
      }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<main id="vue">
      <!-- Safari allows dragging behind scroll bar
      We fix it by shrinking its width on the right side via both
      its range value      :max="windowWidth - 12"
      and its width (CSS)   width: calc(100% - 12px)
      ...synchronously  -->
      <input
        id="split-grabber"
        type="range" 
        v-model="splitWidth"
        :max="windowWidth - 12"
      >
      <article
      class="article"
      :style="{'flex': flexRatio}"
      >
        <section
        class="section section-left">
          splitWidth:{{ splitWidth }}px<br>
          “There was a rich man who always dressed in the finest clothes and lived in luxury every day.
          And a very poor man named Lazarus, whose body was covered with sores, was laid at the rich man’s gate.
          He wanted to eat only the small pieces of food that fell from the rich man’s table. And the dogs would come and lick his sores.
          Later, Lazarus died, and the angels carried him to the arms of Abraham. The rich man died, too, and was buried.
          In the place of the dead, he was in much pain. The rich man saw Abraham far away with Lazarus at his side.
          He called, ‘Father Abraham, have mercy on me! Send Lazarus to dip his finger in water and cool my tongue, because I am suffering in this fire!’
        </section>  
      </article>
      <article
        class="article"
        :style="{'flex': 1-flexRatio}"  
      >
        <section class="section section-right">
          But Abraham said, ‘Child, remember when you were alive you had the good things in life, but bad things happened to Lazarus. Now he is comforted here, and you are suffering.
          Besides, there is a big pit between you and us, so no one can cross over to you, and no one can leave there and come here.’
          The rich man said, ‘Father, then please send Lazarus to my father’s house.
          I have five brothers, and Lazarus could warn them so that they will not come to this place of pain.’
          But Abraham said, ‘They have the law of Moses and the writings of the prophets; let them learn from them.’
          The rich man said, ‘No, father Abraham! If someone goes to them from the dead, they would believe and change their hearts and lives.’
          But Abraham said to him, ‘If they will not listen to Moses and the prophets, they will not listen to someone who comes back from the dead.’”        
        </section>
      </article>
    </main>


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