Подтвердить что ты не робот

Лучший способ сделать разделение панели в html

Кто-нибудь знает о хорошей технике для создания изменяемой области разделения в html?

Можно ли это сделать, используя css/jquery/javascript или кто-нибудь знает хорошую библиотеку javascript, которую они использовали?

(Пример разделенной панели - это панель избранного в Internet Explorer, которую вы можете состыковать слева от вашего главного окна браузера)

4b9b3361

Ответ 2

Мне нужен ваниль, легкий (jQuery UI Layout весит 185 кбайт), нет зависимости (все существующие библиотеки требуют jQuery), поэтому я написал Split.js.

Он весит менее 2 КБ и не требует специальной разметки. Он поддерживает старые браузеры обратно в IE9 (или IE8 с полиполками). Для современных браузеров вы можете использовать его с макетами Flexbox и сетки.

Ответ 3

Вот мой легкий подход vanilla js, используя flexbox:

http://codepen.io/lingtalfi/pen/zoNeJp

Протестировано успешно в chrome 54, firefox 50, safari 10, не знают о других браузерах.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.rawgit.com/lingtalfi/simpledrag/master/simpledrag.js"></script>

    <style type="text/css">

        html, body {
            height: 100%;
        }

        .panes-container {
            display: flex;
            width: 100%;
            overflow: hidden;
        }

        .left-pane {
            width: 18%;
            background: #ccc;
        }

        .panes-separator {
            width: 2%;
            background: red;
            position: relative;
            cursor: col-resize;
        }

        .right-pane {
            flex: auto;
            background: #eee;
        }

        .panes-container,
        .panes-separator,
        .left-pane,
        .right-pane {
            margin: 0;
            padding: 0;
            height: 100%;
        }

    </style>

</head>

<body>

<div class="panes-container">
    <div class="left-pane" id="left-pane">
        <p>I'm the left pane</p>
        <ul>
            <li><a href="#">Item 1</a></li>
            <li><a href="#">Item 2</a></li>
            <li><a href="#">Item 3</a></li>
        </ul>
    </div>
    <div class="panes-separator" id="panes-separator"></div>
    <div class="right-pane" id="right-pane">
        <p>And I'm the right pane</p>
        <p>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. A accusantium at cum cupiditate dolorum, eius eum
            eveniet facilis illum maiores molestiae necessitatibus optio possimus sequi sunt, vel voluptate. Asperiores,
            voluptate!
        </p>
    </div>
</div>


<script>


    var leftPane = document.getElementById('left-pane');
    var rightPane = document.getElementById('right-pane');
    var paneSep = document.getElementById('panes-separator');

    // The script below constrains the target to move horizontally between a left and a right virtual boundaries.
    // - the left limit is positioned at 10% of the screen width
    // - the right limit is positioned at 90% of the screen width
    var leftLimit = 10;
    var rightLimit = 90;


    paneSep.sdrag(function (el, pageX, startX, pageY, startY, fix) {

        fix.skipX = true;

        if (pageX < window.innerWidth * leftLimit / 100) {
            pageX = window.innerWidth * leftLimit / 100;
            fix.pageX = pageX;
        }
        if (pageX > window.innerWidth * rightLimit / 100) {
            pageX = window.innerWidth * rightLimit / 100;
            fix.pageX = pageX;
        }

        var cur = pageX / window.innerWidth * 100;
        if (cur < 0) {
            cur = 0;
        }
        if (cur > window.innerWidth) {
            cur = window.innerWidth;
        }


        var right = (100-cur-2);
        leftPane.style.width = cur + '%';
        rightPane.style.width = right + '%';

    }, null, 'horizontal');


</script>

</body>
</html>

Этот HTML-код зависит от simpledrag облегченной библиотеки vanilla js (менее 60 строк кода).

Ответ 4

В старые времена для этого вы использовали бы фреймы. Существует несколько причин, почему такой подход не так хорош. См. Ответ Reece на почему кадры плохие. См. Также Jakob Nielson Почему Frames Suck (большую часть времени)

Несколько более новый подход заключается в использовании встроенных фреймов. У этого есть плюсы и минусы: Являются ли iframe считающимися "плохой практикой" ?

Еще лучше использовать фиксированное позиционирование. Поместив навигационный контент (например, ссылки избранных в вашем примере) в элемент блока (например, div), затем применив position:fixed к этому элементу и установите свойства слева, сверху и снизу, как это:

#myNav {
    position:fixed;
    left:0px;
    top:0px;
    bottom:0px;
    width:200px;
}

... вы достигнете вертикального столбца в левой части страницы, который не будет перемещаться, когда пользователь прокручивает страницу.

Остальная часть содержимого на странице не будет "ощущать" присутствие этого элемента nav, поэтому он должен учитывать 200px пространства, которое он занимает. Вы можете сделать это, поместив остальную часть содержимого в другой div и установив margin-left:200px;.

Ответ 5

Я написал простой код для него без какой-либо сторонней библиотеки; Этот код предназначен только для горизонтального сплиттера (вертикаль такая же)

function onload()
{
	dragElement( document.getElementById("seperator"), "H" );
}

// function is used for dragging and moving
function dragElement( element, direction, handler )
{
  // Two variables for tracking positions of the cursor
  const drag = { x : 0, y : 0 };
  const delta = { x : 0, y : 0 };
  /* if present, the handler is where you move the DIV from
     otherwise, move the DIV from anywhere inside the DIV */
  handler ? ( handler.onmousedown = dragMouseDown ): ( element.onmousedown = dragMouseDown );

  // function that will be called whenever the down event of the mouse is raised
  function dragMouseDown( e )
  {
    drag.x = e.clientX;
    drag.y = e.clientY;
    document.onmousemove = onMouseMove;
    document.onmouseup = () => { document.onmousemove = document.onmouseup = null; }
  }

  // function that will be called whenever the up event of the mouse is raised
  function onMouseMove( e )
  {
    const currentX = e.clientX;
    const currentY = e.clientY;

    delta.x = currentX - drag.x;
    delta.y = currentY - drag.y;

    const offsetLeft = element.offsetLeft;
    const offsetTop = element.offsetTop;

	
	const first = document.getElementById("first");
	const second = document.getElementById("second");
	let firstWidth = first.offsetWidth;
	let secondWidth = second.offsetWidth;
  if (direction === "H" ) // Horizontal
	{
		element.style.left = offsetLeft + delta.x + "px";
		firstWidth += delta.x;
		secondWidth -= delta.x;
	}
    drag.x = currentX;
    drag.y = currentY;
	first.style.width = firstWidth + "px";
	second.style.width = secondWidth + "px";
  }
}
.splitter {
	width: 500px;
	height: 100px;
	display: flex;
}

#seperator {
	cursor: col-resize;
	background: url(https://raw.githubusercontent.com/RickStrahl/jquery-resizable/master/assets/vsizegrip.png) center center no-repeat #535353;	
	width: 10px;
	height: 100px;
	min-width: 10px;
}

#first {
	background-color: green;
	width: 100px;
	height: 100px;
	min-width: 10px;
}

#second {
	background-color: red;
	width: 390px;
	height: 100px;
	min-width: 10px;
}
<html>
<head>
<link rel="stylesheet" href="T10-Splitter.css">
<script src="T10-Splitter.js"></script>
</head>
<body onload="onload()">
<div class="splitter">
	<div id="first"></div>
	<div id="seperator"></div>
	<div id="second"></div>
</div>
</body>
</html>

Ответ 6

Один совершенно другой подход состоит в том, чтобы помещать вещи в сетку, например, сетку ui-grid или сетку Kendo, и изменять столбцы. Недостатком является то, что пользователи не смогут изменять размер строк, хотя размер строки может быть установлен программно.

Ответ 8

Вы можете использовать абсолютное фиксированное позиционирование. Этот CSS, например, установит 2-мерную панель в левой части страницы:

body {
    padding-left: 2.5em;
}
body > #bar {
    position:fixed;
    top:0; left:0;
    width: 2em;
    height: 100%;
    border-right: 2px solid #55F; background: #ddd;
}

(Демо на jsfiddle.net)

Ответ 10

Вы можете сделать это с помощью JqueryUI без другой JS-библиотеки. Просто добавьте функцию в событие .resizable resize, чтобы настроить ширину другого div.

$("#left_pane").resizable({
  handles: 'e',  // 'East' side of div draggable
  resize: function() {
  $("#right_pane").outerWidth( $("#container").innerWidth() - $("#left_pane").outerWidth() );
  }
});

Здесь полный JS Fiddle.

Ответ 11

Я нашел рабочий сплиттер http://www.dreamchain.com/split-pane/, который работает с jquery v1.9. Заметьте, мне пришлось добавить следующий CSS-код, чтобы он работал с фиксированной панелью навигации bootstrap.

fixed-left {
    position: absolute !important; /* to override relative */   
    height: auto !important;
    top: 55px; /* fixed navbar height */
    bottom: 0px;
}

Ответ 12

Улучшение от Резы:

  • запретить браузеру мешать перетаскиванию
  • предотвратить установку элемента в отрицательный размер
  • предотвратить потерю синхронизации с мышью из-за инкрементного дельта-взаимодействия с насыщением ширины элемента

<html><head><style>

.splitter {
    width: 100%;
    height: 100px;
    display: flex;
}

#separator {
    cursor: col-resize;
    background-color: #aaa;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='30'><path d='M2 0 v30 M5 0 v30 M8 0 v30' fill='none' stroke='black'/></svg>");
    background-repeat: no-repeat;
    background-position: center;
    width: 10px;
    height: 100%;

/* prevent browser built-in drag from interfering */
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

#first {
    background-color: #dde;
    width: 20%;
    height: 100%;
    min-width: 10px;
}

#second {
    background-color: #eee;
    width: 80%;
    height: 100%;
    min-width: 10px;
}

</style></head><body>

<div class="splitter">
	<div id="first"></div>
	<div id="separator" ></div>
	<div id="second" ></div>
</div>

<script>

// function is used for dragging and moving
function dragElement( element, direction)
{
    var   md; // remember mouse down info
    const first  = document.getElementById("first");
    const second = document.getElementById("second");
    
    element.onmousedown = onMouseDown;
    
    function onMouseDown( e )
    {
	//console.log("mouse down: " + e.clientX);
	md = {e,
	      offsetLeft:  element.offsetLeft,
	      offsetTop:   element.offsetTop,
	      firstWidth:  first.offsetWidth,
	      secondWidth: second.offsetWidth};
	document.onmousemove = onMouseMove;
	document.onmouseup = () => { 
	    //console.log("mouse up");
	    document.onmousemove = document.onmouseup = null;
	}
    }
    
    function onMouseMove( e )
    {
	//console.log("mouse move: " + e.clientX);
	var delta = {x: e.clientX - md.e.x,
		     y: e.clientY - md.e.y};
	
	if (direction === "H" ) // Horizontal
	{
	    // prevent negative-sized elements
	    delta.x = Math.min(Math.max(delta.x, -md.firstWidth),
			       md.secondWidth);
	    
	    element.style.left = md.offsetLeft + delta.x + "px";
	    first.style.width = (md.firstWidth + delta.x) + "px";
	    second.style.width = (md.secondWidth - delta.x) + "px";
	}
    }
}


dragElement( document.getElementById("separator"), "H" );

</script></body></html>

Ответ 13

Хорошей библиотекой является пользовательский интерфейс Shield - вы можете взглянуть на их гибкий виджет Splitter и остальные мощные компоненты, предлагаемые каркасом.

Ответ 14

Простейший аккордеон, с размером CSS. Переполнение правила тоже должно быть установлено.

div {
  resize: vertical;
  overflow: auto;
  
  border: 1px solid
}

.menu {
  display: grid
  /* Try height: 100% or height: 100vh */
}
<div class="menu">

  <div>
    Hello world! 
  </div>
  <div>
    Hello world! 
  </div>
  <div>
    Hello world! 
  </div>
  <div>
    Hello world! 
  </div>
  <div>
    Hello world! 
  </div>
  <div>
    Hello world! 
  </div>
  
</div>