我有一个ul
列表,其中每个list-item (li)
动态更新。在特定li
的每个新数据上,我想通过jQuery应用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/
答案 0 :(得分:3)
好的,从CSS开始:要进行转换,您需要指定从转换的内容以及将转换为>的内容,过渡时间应该在&#34;之前&#34;州(你在&#34;&#34;州之后)。
所以你的CSS看起来像这样:
li {background-color: #FFF; transition: all 0.2s}
.effect { background-color: rgba(45, 171, 64, 0.1) }
(&#39;没有效果&#39; li有背景颜色和过渡时间;&#39;有效&#39;有不同的背景颜色。)
现在开始使用javascript:
if (!$('.list-item').hasClass('effect')){
$('.list-item').addClass('effect');
那&#34; if&#34;在这里是无害的,但没有必要。您只需致电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
});
&#13;
li {transition: all 0.2s; background-color:#FFF}
.effect { background-color: rgba(45, 171, 64, 0.1); }
&#13;
<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>
&#13;
(当然在现实生活中你可能想要将它应用于单个列表项而不是所有这些列表项;如评论中的声音,就像你已经控制了那部分一样)。
评论者指出,您可以通过在删除和重新添加类之间从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');
});
&#13;
li {
background-color: #FFF; padding: 0.5em
}
li.effect {
background-color: #FFC;
transition: all 1s;
}
.b {
transition: all 1s;
}
&#13;
<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>
&#13;
答案 1 :(得分:1)
理想的解决方案,没有不必要的setTimeouts,元素克隆等。必须在浏览器中强制重排流程,因为浏览器正在批处理 - 具有&#34;懒惰的方法&#34; - 写给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')
}
})
})
&#13;
.effect {
transition: all 1s;
background-color: yellow;
}
&#13;
<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>
&#13;
答案 2 :(得分:0)
以下是使用按钮单击事件来回切换列表项类的示例。请参阅下面的代码段,了解如何删除或添加绿色背景类:
$(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>
答案 3 :(得分:0)
请尝试这一点,只需点击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>