为啥取消选择不适用于可选择和可拖动的多个项目

Posted

技术标签:

【中文标题】为啥取消选择不适用于可选择和可拖动的多个项目【英文标题】:why unselection is not working for multiple items with selectable and draggable为什么取消选择不适用于可选择和可拖动的多个项目 【发布时间】:2020-06-19 21:54:56 【问题描述】:

我希望我的unselection 的列表项能像没有.draggable().selectable() 一样流畅地工作

我的期望类似于gifselectabledraggable 的组合:

上面的代码没有draggable:

   $("#selectable").selectable();
  #feedback 
      font-size: 1.4em;
  
  #selectable .ui-selecting 
      background: #FECA40;
  
  #selectable .ui-selected 
      background: #F39814;
      color: white;
  
  #selectable 
      list-style-type: none;
      margin: 0;
      padding: 0;
      width: 60%;
  
  #selectable li 
      margin: 3px;
      padding: 0.4em;
      font-size: 1.4em;
      height: 18px;
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>

<ol id="selectable">
    <li class="ui-widget-content">Item 1</li>
    <li class="ui-widget-content">Item 2</li>
    <li class="ui-widget-content">Item 3</li>
    <li class="ui-widget-content">Item 4</li>
    <li class="ui-widget-content">Item 5</li>
    <li class="ui-widget-content">Item 6</li>
    <li class="ui-widget-content">Item 7</li>
</ol>

问题: 下面结合 selectabledraggable selectionunselection 不能像上面的代码一样工作,只有 selectable

这是我尝试过的:

$(function() 
    $( "#selectable" ).selectable(
           start: function (event, ui) 
                 /* $('.ui-widget-content').draggable('destroy') */;
             ,
       stop: function(event,ui)
           $('.ui-widget-content').draggable(
               drag: function(event,ui)
                  console.log('dragging....');
                  $('#multiple_selected_rows').remove();
                  var elem = document.createElement("div");
                  elem.id = "multiple_selected_rows";
                  elem.innerText = $('li.ui-selected').length+" items";
                  document.body.appendChild(elem);
                  
                   $("#multiple_selected_rows").css( 'top': event.clientY + 10, 'left': event.clientX + 10 );
               
           );
           $( "#selectable" ).selectable();
       
    );
    
    $('#droppable').droppable(
        accept: '.ui-widget-content',
        greedy: true,
        drop: function (event, ui) 
           $('#multiple_selected_rows').remove();
           
    );
 );
#feedback  font-size: 1.4em; 
  #selectable .ui-selecting  background: #FECA40; 
  #selectable .ui-selected  background: #F39814; color: white; 
  #selectable  list-style-type: none; margin: 0; padding: 0; /*width: 60%;*/ padding:22px; border: solid 1px #0973c7;
  #selectable li  margin: 8px; padding:10px; border:solid 1px #CCC;
  .ui-selectable-helper  position: absolute; z-index: 100; border:1px dotted black;  

#main-container
    display: flex;
    justify-content: space-between;


div#main-container .demo 
    width: 50%;
    margin-right: 7px;


div#main-container #droppable 
    flex: 1;
    border: 1px solid red;


#multiple_selected_rows
   position:absolute;
   width: 90px;
   height:40px;
   background:red;
   color: #fff;
   text-align: center;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet"/>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>


<div id="main-container">
     <div class="demo">
        <ol id="selectable">
          <li class="ui-widget-content">Item 1</li>
          <li class="ui-widget-content">Item 2</li>
          <li class="ui-widget-content">Item 3</li>
          <li class="ui-widget-content">Item 4</li>
          <li class="ui-widget-content">Item 5</li>
          <li class="ui-widget-content">Item 6</li>
          <li class="ui-widget-content">Item 7</li>
        </ol>
    </div>
    <div id="droppable">
        
    </div>
</div>

请帮助我提前谢谢!!!!!!

【问题讨论】:

您是否尝试过在背景中添加过渡,这可能会产生更好的效果 我建议在项目的右侧或左侧添加一个可拖动的手柄,这样您只有在将鼠标悬停在手柄上时才能拖动。 @Souleste 我同意。这是保持示例 gif 中显示的选择方法同时仍允许拖动项目的唯一方法。有关工作示例,请参阅我的答案的最后一部分。 【参考方案1】:

注意:如果您要拖动选择的项目到另一个盒子。您可以使用selectable() 拖动选择项,也可以使用draggable() 拖动(即移动)您选择的项目,不能同时使用两者。


您的selectable()draggable() 方法正在相互竞争相同的鼠标事件。所以不要在页面加载时设置它们,试试这个:

selectable()stop回调中,将选中的元素包裹在一个div中:

$('.ui-selected').wrapAll('<div id="dragSet"></div>');

然后在#dragSet 上致电draggable()。现在,此调用将优先于所选项目的 selectable() 鼠标事件。

draggable() stop 回调中,将所选项目附加到#droppable 并删除它们的.ui-selected 类。

$('#droppable').append( $('#dragSet') );
$('#dragSet').contents().unwrap();
$('#droppable li').removeClass('ui-selected'); 

最后,为selectable() start 回调添加一些逻辑,以防止双重包装您的选择。

if ( $('#dragSet').children().length > 0 ) $('#dragSet').contents().unwrap();
else $('#dragSet').remove(); 

请参阅下面的工作示例:

$(function() 
  $("#selectable").selectable(
    start: function(event, ui) 
      if ($('#dragSet').children().length > 0) $('#dragSet').contents().unwrap();
      else $('#dragSet').remove();
    ,
    stop: function(event, ui) 
      $('.ui-selected').wrapAll('<div id="dragSet"></div>');
      $('#dragSet').draggable(
        stop: function(event, ui) 
          $('#droppable').append($('#dragSet'));
          $('#dragSet').contents().unwrap();
          $('#droppable li').removeClass('ui-selected');
        
      );
    
  );
);
#feedback 
  font-size: 1.4em;


#selectable .ui-selecting 
  background: #FECA40;


#selectable .ui-selected 
  background: #F39814;
  color: white;


#selectable 
  list-style-type: none;
  margin: 0;
  padding: 0;
  /*width: 60%;*/
  padding: 22px;
  border: solid 1px #0973c7;


#selectable li 
  margin: 8px;
  padding: 10px;
  border: solid 1px #CCC;


.ui-selectable-helper 
  position: absolute;
  z-index: 100;
  border: 1px dotted black;


#main-container 
  display: flex;
  justify-content: space-between;


div#main-container .demo 
  width: 50%;
  margin-right: 7px;


div#main-container #droppable 
  flex: 1;
  border: 1px solid red;


#multiple_selected_rows 
  position: absolute;
  width: 90px;
  height: 40px;
  background: red;
  color: #fff;
  text-align: center;


#droppable li.ui-widget-content 
  margin: 8px;
  padding: 10px;
  border: solid 1px #ccc;
  color: white;
  background: green;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>


<div id="main-container">
  <div class="demo">
    <ol id="selectable">
      <li class="ui-widget-content">Item 1</li>
      <li class="ui-widget-content">Item 2</li>
      <li class="ui-widget-content">Item 3</li>
      <li class="ui-widget-content">Item 4</li>
      <li class="ui-widget-content">Item 5</li>
      <li class="ui-widget-content">Item 6</li>
      <li class="ui-widget-content">Item 7</li>
    </ol>
  </div>
  <div id="droppable">

  </div>
</div>

奖金:

要来回拖动,重复相同的 JS 并将 #selectable#droppable 交换。

$(function() 
  $("#selectable").selectable(
    start: function(event, ui) 
      if ($('#dragSet').children().length > 0) $('#dragSet').contents().unwrap();
      else $('#dragSet').remove();
    ,
    stop: function(event, ui) 
      $('.ui-selected').wrapAll('<div id="dragSet"></div>');
      $('#dragSet').draggable(
        stop: function(event, ui) 
          $('#droppable').append($('#dragSet'));
          $('#dragSet').contents().unwrap();
          $('#droppable li').removeClass('ui-selected');
        
      );
    
  );

  $("#droppable").selectable(
    start: function(event, ui) 
      if ($('#dragSet').children().length > 0) $('#dragSet').contents().unwrap();
      else $('#dragSet').remove();
    ,
    stop: function(event, ui) 
      $('.ui-selected').wrapAll('<div id="dragSet"></div>');
      $('#dragSet').draggable(
        stop: function(event, ui) 
          $('#selectable').append($('#dragSet'));
          $('#dragSet').contents().unwrap();
          $('#selectable li').removeClass('ui-selected');
        
      );
    
  );
);
#feedback 
  font-size: 1.4em;


#selectable .ui-selecting,
#droppable .ui-selecting 
  background: #FECA40;


#selectable .ui-selected,
#droppable .ui-selected 
  background: #F39814;
  color: white;


#selectable,
#droppable 
  list-style-type: none;
  margin: 0;
  padding: 0;
  padding: 22px;
  border: solid 1px #0973c7;


#selectable li,
#droppable li 
  margin: 8px;
  padding: 10px;
  border: solid 1px #CCC;


.ui-selectable-helper 
  position: absolute;
  z-index: 100;
  border: 1px dotted black;


#main-container 
  display: flex;
  justify-content: space-between;


div#main-container .demo 
  width: 50%;
  margin-right: 7px;


div#main-container #droppable 
  flex: 1;
  border: 1px solid red;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>


<div id="main-container">
  <div class="demo">
    <ol id="selectable">
      <li class="ui-widget-content">Item 1</li>
      <li class="ui-widget-content">Item 2</li>
      <li class="ui-widget-content">Item 3</li>
      <li class="ui-widget-content">Item 4</li>
      <li class="ui-widget-content">Item 5</li>
      <li class="ui-widget-content">Item 6</li>
      <li class="ui-widget-content">Item 7</li>
    </ol>
  </div>
  <div id="droppable">

  </div>
</div>

Selectable and Draggable with selection 如 gif 所示:

通常,您需要单击所选项目才能拖动它们。但是由于您希望能够单击它们以进行新选择,因此您需要添加另一个元素作为手柄来拖动它们。

$(function() 
  $( "#selectable" ).selectable(      
    start: function (event, ui) 
        if ( $('#dragSet').children().length > 0 ) 
          $('#dragHandle').remove();
          $('#dragSet').contents().unwrap();
        
        else $('#dragSet').remove();        
    ,
    stop: function(event,ui)        
      $('.ui-selected').wrapAll('<div id="dragSet"></div>');
      $('#dragSet').append('<div id="dragHandle">Drag Me</div>');
      $('#dragHandle').on('mouseenter', function() 
        $('#dragSet').draggable(
          stop: function(event, ui)            
            $('#droppable').append( $('#dragSet') );
            $('#dragHandle').remove();
            $('#dragSet').contents().unwrap();
            $('#droppable li').removeClass('ui-selected');          
          
        );
      ).on('mouseleave', function() 
        $('#dragSet').draggable('destroy');
      ); 
    
  );

  $( "#droppable" ).selectable(      
    start: function (event, ui) 
        if ( $('#dragSet').children().length > 0 ) 
          $('#dragHandle').remove();
          $('#dragSet').contents().unwrap();          
        
        else $('#dragSet').remove();        
    ,
    stop: function(event,ui)        
      $('.ui-selected').wrapAll('<div id="dragSet"></div>');
      $('#dragSet').append('<div id="dragHandle">Drag Me</div>');
      $('#dragHandle').on('mouseenter', function() 
        $('#dragSet').draggable(
          stop: function(event, ui)            
            $('#selectable').append( $('#dragSet') );
            $('#dragHandle').remove();
            $('#dragSet').contents().unwrap();
            $('#selectable li').removeClass('ui-selected');          
          
        );
      ).on('mouseleave', function() 
        $('#dragSet').draggable('destroy');
      );
    
  );
 );
#feedback  
  font-size: 1.4em; 


#selectable .ui-selecting,
#droppable .ui-selecting  
  background: #FECA40; 


#selectable .ui-selected,
#droppable .ui-selected  
  background: #F39814; 
  color: white; 


#selectable, 
#droppable  
  list-style-type: none; 
  margin: 0; 
  padding: 0; 
  padding:22px; 
  border: solid 1px #0973c7;


#selectable li,
#droppable li  
  margin: 8px; 
  padding:10px; 
  border:solid 1px #CCC;


.ui-selectable-helper  
  position: absolute; 
  z-index: 100; 
  border:1px dotted black; 
 

#main-container
  display: flex;
  justify-content: space-between;


div#main-container .demo 
  width: 50%;
  margin-right: 7px;


div#main-container #droppable 
  flex: 1;
  border: 1px solid red;


#dragSet 
  position: relative;


#dragHandle 
  position: absolute;
  top: 4px;
  right: 12px;
  background-color: red;
  color: white;
  padding: 6px;
  border: 1px solid black;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>


<div id="main-container">
  <div class="demo">
    <ol id="selectable">
      <li class="ui-widget-content">Item 1</li>
      <li class="ui-widget-content">Item 2</li>
      <li class="ui-widget-content">Item 3</li>
      <li class="ui-widget-content">Item 4</li>
      <li class="ui-widget-content">Item 5</li>
      <li class="ui-widget-content">Item 6</li>
      <li class="ui-widget-content">Item 7</li>
    </ol>
  </div>
  <div id="droppable">

  </div>
</div>

【讨论】:

这很好,但un-selection 并没有按照有问题的 gif 图像中的要求发生 我主要关心的是根据 gif 进行选择和取消选择 @EaBengaluru 如果单击它们取消选择组,您希望如何将项目拖动到您的#droppable 框中?您的问题是如何组合selectable()draggable()。他们都需要点击。如果您想选择与 gif 中所示相同的方式,则必须放弃 draggable() 并创建一个将选择转移到另一个框的按钮。 我最不关心drag 功能,我会以某种方式处理。但我不想删除draggable。我现在最烦恼的是选择,取消选择

以上是关于为啥取消选择不适用于可选择和可拖动的多个项目的主要内容,如果未能解决你的问题,请参考以下文章

为啥专注于输入框和选项不适用于引导模式?

使用 jQuery Sortables 拖动项目时单选按钮被取消选择

可拖动+可排序和可滚动的 div

可选择和可拖动的 jQuery 以创建类似 Windows 资源管理器的窗口

stopPropagation 不适用于可拖动的 resizble div

jQuery-UI 可拖动和可放置项目变为不可拖动