jQuery UI 排序触发 css3 排序动画

jQuery UI sortable triggers css3 animation on sort

我有一些 sortables 通过 class 在它们上面定义了 CSS3 关键帧动画。排序时,我注意到 this Fiddle.

中的奇怪行为
.slideLeft {
  animation-name: slideLeft;
  -webkit-animation-name: slideLeft;    

  animation-duration: 1s;   
  -webkit-animation-duration: 1s;

  animation-timing-function: ease-in-out;   
  -webkit-animation-timing-function: ease-in-out;       

  visibility: visible !important;   
}

@keyframes slideLeft {
  0% {
     transform: translateX(150%);
  }
  50%{
    transform: translateX(-8%);
  }
  65%{
    transform: translateX(4%);
  }
  80%{
    transform: translateX(-4%);
  }
  95%{
    transform: translateX(2%);
  }         
  100% {
    transform: translateX(0%);
  }
}

正在启动 jQuery 可排序。

$(function() {
  $( "#sortable" ).sortable();
});

动画在排序 startstop 时触发,而动画 class 未被重新应用。 jQuery 修改 DOM 似乎导致了某种回流。但是它是如何一直触发动画的,又是如何避免的呢?目标是在排序时完全没有动画,同时保持 class.

答案: 这是有道理的,因为我们拖动的项目只是一个克隆,它在 start 因为我们将克隆插入到 DOM。 stop 上发生的动画具有相同的原因,因为克隆随后被附加到它的新位置,再次触发文档的重排。

您使用 !important 强制显示占位符 li。

    .slideLeft {
        animation-name: slideLeft;
        -webkit-animation-name: slideLeft;  

        animation-duration: 1s; 
        -webkit-animation-duration: 1s;

        animation-timing-function: ease-in-out; 
        -webkit-animation-timing-function: ease-in-out;     

        visibility: visible !important; 
    }

如果您在 jfiddle 中检查,您会看到 ui-sortable-placeholder 具有内联

    style="visibility:hidden;"

它正在被上面 css 中的最后一行覆盖。你可以用类似的东西重新覆盖它:

    .ui-sortable-placeholder{
         visibility: hidden !important;    

     }

或类似的东西。这将使幻灯片左侧部分不可见,只显示动画的 "bounce" 部分(不确定这是否是您想要的)。

您可以将其添加到您的脚本下方

setTimeout(function(){
    $( "#sortable" ).children("li").first().removeClass('slideLeft');
}, 1000);

此脚本等待动画结束(1000 毫秒),然后从第一个列表项中删除 class slideLeft。但是,如果您速度很快并且 select 在第二行中的第一行,问题仍然存在。所以我要做的是将你的脚本包装在超时函数周围:

setTimeout(function(){
    $(function() {
        $( "#sortable" ).sortable();
    });
    $( "#sortable" ).children("li").first().removeClass('slideLeft');
}, 1000);

这会等待一秒钟(1000 毫秒)以使列表可排序。在那一秒之后,它还会删除 class slideLeft 以防止继续动画。缺点是你无法对列表进行 1 秒的排序。

这是基于您的脚本的完整 fiddle:

setTimeout(function() {
  $(function() {
    $("#sortable").sortable();
  });
  $("#sortable").children("li").first().removeClass('slideLeft');
}, 1000);
#sortable {
  list-style-type: none;
  margin: 0;
  padding: 0;
  width: 60%;
}
#sortable li {
  margin: 0 3px 3px 3px;
  padding: 0.4em;
  padding-left: 1.5em;
  font-size: 1.4em;
  height: 18px;
}
#sortable li span {
  position: absolute;
  margin-left: -1.3em;
}
.slideLeft {
  animation-name: slideLeft;
  -webkit-animation-name: slideLeft;
  animation-duration: 1s;
  -webkit-animation-duration: 1s;
  animation-timing-function: ease-in-out;
  -webkit-animation-timing-function: ease-in-out;
  visibility: visible !important;
}
@keyframes slideLeft {
  0% {
    transform: translateX(150%);
  }
  50% {
    transform: translateX(-8%);
  }
  65% {
    transform: translateX(4%);
  }
  80% {
    transform: translateX(-4%);
  }
  95% {
    transform: translateX(2%);
  }
  100% {
    transform: translateX(0%);
  }
}
@-webkit-keyframes slideLeft {
  0% {
    -webkit-transform: translateX(150%);
  }
  50% {
    -webkit-transform: translateX(-8%);
  }
  65% {
    -webkit-transform: translateX(4%);
  }
  80% {
    -webkit-transform: translateX(-4%);
  }
  95% {
    -webkit-transform: translateX(2%);
  }
  100% {
    -webkit-transform: translateX(0%);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/i18n/jquery-ui-i18n.min.js"></script>
<script src="http://jquery-ui.googlecode.com/svn/tags/latest/external/jquery.bgiframe-2.1.2.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<link href="http://static.jquery.com/ui/css/demo-docs-theme/ui.theme.css" rel="stylesheet"/>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css" rel="stylesheet"/>
<ul id="sortable">
  <li class="ui-state-default slideLeft"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 1</li>
  <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 2</li>
  <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 3</li>
  <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 4</li>
  <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 5</li>
  <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 6</li>
  <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>Item 7</li>
</ul>

我认为,您需要在动画完成后从 li 项目中删除 slideLeft class。类似于:

$(function(){
    $( "#sortable" ).sortable();
    //one second later the slideLeft class  is removed from each li.
    window.setTimeout(function(){
      $( "#sortable" ).find(".slideLeft").removeClass("slideLeft");
    }, 1000)

});

希望对你有用。

PD.

排序列表时,jquery-ui 更改了 DOM,因为元素被删除并再次插入。此外 jquery-ui 创建另一个与占位符具有相同属性的元素,显示移动元素的位置。

然后如果您不删除 slideLeft class,动画将随着列表中的每个变化播放

如果你想保留class,但需要阻止动画,你可以这样做:

$("#sortable").sortable({
    beforeStop: function( event, ui ) {
       $(ui.item).css("animation", "none");
    }
});

最好输入你的 css:

#sortable .ui-sortable-placeholder { visibility: hidden !important; animation: none; }

您的 fiddle 工作:http://jsfiddle.net/Lvnzffoh/1/