繁体   English   中英

通过jQuery或javascript重新启动CSS转换

[英]Restart css transition via jQuery or javascript

我有一个ul列表,其中每个list-item (li)动态更新。 我想通过jQuery在特定li每个新数据上应用css效果。

当前的HTML是:

<ul>
 <li class="list-item">data0</li>
 <li class="list-item">data1</li>
</ul>

更改<li>data0</li> ,我想应用css效果,将li的背景颜色从白色更改为绿色,并保持绿色。 当我想再次将背景更改为白色然后再次更改为绿色时,再次更新该li

我当前的jQuery逻辑是这样,但似乎不起作用:

if (!$('.list-item').hasClass('effect')){
     $('.list-item').addClass('effect');
} else {
     $('.list-item').removeClass('effect');
     $('.list-item').addClass('effect');
}

效果CSS:

.effect { background-color: rgba(45, 171, 64, 0.1); transition: 0.2s; } 

list-item CSS类未设置任何背景设置。

这是当前代码的jsfiddle: http : //jsfiddle.net/dwmahagq/

好的,从CSS开始:要进行过渡,您需要指定要从中进行过渡以及要过渡到的对象 ,过渡时间应处于“之前”状态(您可以在“之后”状态)。

因此,您的CSS可能如下所示:

li {background-color: #FFF; transition: all 0.2s}
.effect { background-color: rgba(45, 171, 64, 0.1) } 

(“无效果” li具有背景色和过渡时间;“有效果” li具有不同的背景色。)

现在开始使用javascript:

if (!$('.list-item').hasClass('effect')){
     $('.list-item').addClass('effect');

该“如果”是无害的,但在这里是不必要的。 您可以调用addClass添加一个类; 如果元素已经具有该类,则不会发生任何事情。

} else {
     $('.list-item').removeClass('effect');
     $('.list-item').addClass('effect');

我认为即使在已经生效的元素上,您也要尝试再次触发过渡---这将无法按您的方式进行,因为JavaScript会将这些DOM更改汇总在一起,直到DOM为止根本没有任何改变。

相反,您需要删除效果,然后执行setTimeout将其恢复。

将所有这些放在一起会导致:

 $('.test').on("click",function() { $('.list-item').removeClass('effect'); window.setTimeout(function() { $('.list-item').addClass('effect'); }, 200); // <-- same duration as the transition }); 
 li {transition: all 0.2s; background-color:#FFF} .effect { background-color: rgba(45, 171, 64, 0.1); } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <ul> <li class="list-item">data0</li> <li class="list-item">data1</li> </ul> <div class="test">Click</div> 

(实际上,在现实生活中,您可能希望将其应用于单个列表项,而不是将其应用于此处所示的所有列表项;声音听起来就像您已经控制了该部分一样)。

另一种方法

评论者指出,可以通过在删除和重新添加类之间从DOM中读取属性来触发DOM重排,而不是setTimeout

$('.test').on("click", function() {
  $('.list-item').removeClass('effect');
  void this.clientWidth; // read any dom property, doesn't matter which
  $('.list-item').addClass('effect');
});

效果很好,但有一个局限性:效果退出时不能设置任何过渡时间。 (在这种情况下,如果在li设置了过渡持续时间,则动画将不会重新启动;如果仅在li.effect上设置了过渡时间,它将起作用。)演示:

 $('button').click(function() { var li = $(this).prev('li'); li.removeClass('effect'); void this.clientWidth; li.addClass('effect'); }); 
 li { background-color: #FFF; padding: 0.5em } li.effect { background-color: #FFC; transition: all 1s; } .b { transition: all 1s; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <p>Here you can repeat the animation:</p> <li>Item</li> <button>This will work</button> <p>...but here you can't (because the transition time on the 'li' prevents the effect from being visible): <li class="b">Item</li> <button>This will not work</button> 

理想的解决方案,没有不必要的setTimeouts,元素克隆等。必须强制浏览器中的重排过程,因为浏览器是批处理-具有“惰性方法”的dom写入。

 $('button').on('click', function () { $('.list-item').each(function () { $(this).toggleClass('effect') if (!$(this).hasClass('effect')) { // Between two consequent DOM writes, // two .toggleClass() method calls, // insert command which reads DOM. // In other words, give browser no // chance to optimize (batch) // consequent DOM writes. // This creates something called // "layout trashing", which itself // is undesirable effect in most // cases. But as you can see, // sometimes is "the evil" // the simpliest solution :) void this.clientWidth $(this).toggleClass('effect') } }) }) 
 .effect { transition: all 1s; background-color: yellow; } 
 <ul> <li class="list-item">ITEM 1</li> <li class="list-item">ITEM 2</li> </ul> <button>run/restart effect</button> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 

这是一个使用按钮单击事件来回切换列表项类的示例。 请参见下面的代码片段,以了解如何删除或添加绿色背景类:

 $(function(){ $("#switchBtn").click(function(){ if (!$('.list-item').hasClass('effect')){ $('.list-item').addClass('effect'); } else { $('.list-item').removeClass('effect'); //$('.list-item').addClass('effect'); } }); }); 
 .effect { background-color: rgba(45, 171, 64, 0.1); transition: 0.2s; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <ul> <li class="list-item">data0</li> <li class="list-item">data1</li> </ul> <br /> <button id="switchBtn">Switch</button> 

请尝试此操作,只需单击li即可显示效果。

  <!DOCTYPE html> <html> <head> <style> .effect { background-color: rgba(45, 171, 64, 0.1); transition: 0.2s; } </style> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script> $(document).ready(function(){ $("li").click(function(){ $(this).toggleClass("effect"); }); }); </script> </head> <body> <ul> <li class="list-item">data0</li> <li class="list-item">data1</li> </ul> </body> </html> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM