Перетаскиваемые + сортируемые и прокручиваемые элементы управления
-
06-07-2019 - |
Вопрос
У меня есть контейнер со списком перетаскиваемых элементов и контейнер со списком сортируемых элементов.Перетаскиваемые объекты и сортируемый список связаны, что позволяет пользователю перетаскивать клоны перетаскиваемых объектов в отсортированный список.
Перетаскиваемые элементы отображаются в вертикальном списке, однако сортируемые элементы отображаются в горизонтальном списке, что достигается путем их перемещения влево.В контейнере сортируемых элементов для переполнения установлено значение auto, что приводит к появлению горизонтальной полосы прокрутки в случае переполнения содержимого.Два контейнера появляются рядом друг с другом: перетаскиваемые объекты — слева, а сортируемые — справа.
Проблема, с которой я столкнулся, заключается в том, что когда контейнер сортируемых элементов прокручивается вправо, перетаскивание из контейнера перетаскиваемых элементов немедленно запускает события сортируемых элементов.Похоже, что содержимое контейнера сортируемых объектов перемещается за контейнер перетаскиваемых объектов.
Вот мой код:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<head>
<title>Sortables in scrollable divs</title>
<script type="text/javascript" language="JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript" language="JavaScript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>
<script type="text/javascript" language="javascript">
$(function() {
$("#sortable").sortable({
start: function(event, ui) {
if (ui.helper !== null) console.log("sortable \"" + ui.helper.text() + "\" drag start");
},
stop: function(event, ui) {
if (ui.helper !== null) console.log("sortable \"" + ui.helper.text() + "\" drag stopped");
if (ui.item !== null) console.log("sortable item \"" + ui.item.text() + "\" drag stopped");
}
});
$("#sortable").sortable("disable");
$("#draggable li").draggable({
connectToSortable: '#sortable',
helper: 'clone',
revert: 'invalid',
cursor: "default",
cursorAt: { top: -5, left: -5 },
start: function(event, ui) {
if (ui.helper !== null) console.log("draggable \"" + ui.helper.text() + "\" drag start");
},
stop: function(event, ui) {
if (ui.helper !== null) console.log("draggable \"" + ui.helper.text() + "\" drag stopped");
}
});
$("#container2").mouseenter(function() {
console.log("enter sortable container");
$("#sortable").sortable("enable");
}).mouseleave(function() {
console.log("leaving sortable container");
$("#sortable").sortable("disable");
});
$("#draggable, #sortable").disableSelection();
});
</script>
<style type="text/css">
html, body, p, td, th, li, input, select, option, textarea
{
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
color:#343E41;
}
.wrapper
{
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
height: expression(this.parentNode.offsetHeight + "px");
}
.scroll-wrapper
{
position: relative;
width: 100%;
height: 100%;
overflow: auto;
height: expression(this.parentNode.offsetHeight + "px");
}
#container1
{
float:left;
width:200px;
height:400px;
overflow:auto;
border:solid #000 1px;
margin:5px;
}
#container2
{
float:left;
width:600px;
height:400px;
overflow:auto;
border:solid #000 1px;
margin:5px;
}
ul#draggable
{
padding:0;
margin:0;
list-style-image:none;
list-style-position:outside;
list-style-type:none;
}
ul#draggable li
{
display:block;
margin:5px;
border:solid #000 1px;
height:50px;
width:150px;
}
ul#sortable
{
padding:0;
margin:0;
list-style-image:none;
list-style-position:outside;
list-style-type:none;
height:380px;
width:744px;
}
ul#sortable li
{
display:block;
float:left;
margin:5px;
border:solid #000 1px;
height:370px;
width:50px;
text-align:center;
}
</style>
</head>
<body>
<form id="form1" action="">
<div id="container1">
<ul id="draggable">
<li>1A</li>
<li>2A</li>
<li>3A</li>
<li>4A</li>
<li>5A</li>
<li>6A</li>
<li>7A</li>
<li>8A</li>
<li>9A</li>
<li>10A</li>
<li>11A</li>
<li>12A</li>
</ul>
</div>
<div id="container2">
<ul id="sortable">
<li class="ui-state-default">1</li>
<li class="ui-state-default">2</li>
<li class="ui-state-default">3</li>
<li class="ui-state-default">4</li>
<li class="ui-state-default">5</li>
<li class="ui-state-default">6</li>
<li class="ui-state-default">7</li>
<li class="ui-state-default">8</li>
<li class="ui-state-default">9</li>
<li class="ui-state-default">10</li>
<li class="ui-state-default">11</li>
<li class="ui-state-default">12</li>
</ul>
</div>
</form>
</body>
Как я могу избежать срабатывания сортируемых событий до тех пор, пока элемент не будет перетащен в сортируемый контейнер?
заранее спасибо
Решение
Прошло много времени с тех пор, как я публиковал этот вопрос, и с тех пор были выпущены новые версии jQuery и jQuery UI.
Кроме того, команда разработчиков пользовательского интерфейса jQuery добавила пример перетаскивания, связанного с сортируемыми объектами.
Поэтому я обновил исходный пример кода, приведенный выше, и изменил его так, чтобы он соответствовал моему сценарию.Мне нужен сортируемый раздел с горизонтальной прокруткой, который будет автоматически расширяться при добавлении новых элементов.
Мой пример ниже решил мою проблему, и код выглядит намного чище и проще:
$(function () {
$("#sortable").sortable({
revert: true,
start: function (event, ui) {
$(this).width($(this).width() + ui.helper.width() + 12);
},
stop: function (event, ui) {
var w = 0;
$(this).children("li").each(function () {
w += $(this).width() + parseInt($(this).css("margin-left")) + parseInt($(this).css("margin-right")) + 2;
});
$(this).width(w);
}
});
var w = 0;
$("#sortable").children("li").each(function () {
w += $(this).width() + parseInt($(this).css("margin-left")) + parseInt($(this).css("margin-right")) + 2;
});
$("#sortable").width(w);
$("#draggable li").draggable({
connectToSortable: "#sortable",
helper: "clone",
revert: "invalid"
});
$("ul, li").disableSelection();
});
html, body, p, td, th, li, input, select, option, textarea
{
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 11px;
color:#343E41;
}
.wrapper
{
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
height: expression(this.parentNode.offsetHeight + "px");
}
.scroll-wrapper
{
position: relative;
width: 100%;
height: 100%;
overflow: auto;
height: expression(this.parentNode.offsetHeight + "px");
}
#container1
{
float:left;
width:200px;
height:400px;
overflow:auto;
border:solid #000 1px;
margin:5px;
}
#container2
{
float:left;
width:600px;
height:400px;
overflow:auto;
border:solid #000 1px;
margin:5px;
}
ul#draggable
{
padding:0;
margin:0;
list-style-image:none;
list-style-position:outside;
list-style-type:none;
}
ul#draggable li
{
display:block;
margin:5px;
border:solid #000 1px;
height:50px;
width:150px;
}
ul#sortable
{
padding:0;
margin:0;
list-style-image:none;
list-style-position:outside;
list-style-type:none;
height:380px;
}
ul#sortable li
{
display:block;
float:left;
margin:5px;
border:solid #000 1px;
height:370px;
width:50px;
text-align:center;
}
<script type="text/javascript" language="JavaScript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
<script type="text/javascript" language="JavaScript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script>
<form id="form1" action="">
<div id="container1">
<ul id="draggable">
<li>1A</li>
<li>2A</li>
<li>3A</li>
<li>4A</li>
<li>5A</li>
<li>6A</li>
<li>7A</li>
<li>8A</li>
<li>9A</li>
<li>10A</li>
<li>11A</li>
<li>12A</li>
</ul>
</div>
<div id="container2">
<ul id="sortable">
<li class="ui-state-default">1</li>
<li class="ui-state-default">2</li>
<li class="ui-state-default">3</li>
<li class="ui-state-default">4</li>
<li class="ui-state-default">5</li>
<li class="ui-state-default">6</li>
<li class="ui-state-default">7</li>
<li class="ui-state-default">8</li>
<li class="ui-state-default">9</li>
<li class="ui-state-default">10</li>
<li class="ui-state-default">11</li>
<li class="ui-state-default">12</li>
</ul>
</div>
</form>
Подумал, что кто-то где-то захочет сделать то же самое и ему нужна помощь :D