我正在使用JQuery UI来添加类(),然后使用removeClass()。
如果在addClass()完成之前调用removeClass(),它会排队并稍后执行。这不是理想的,我宁愿立即从当前的CSS值执行removeClass()。
如果我在add / removeClass()之前调用stop(),则在stop()调用时动画似乎永久“冻结”,尽管add / removeClass()回调仍然会触发。
这里只是JS:
var obj = $("#obj");
obj.addClass("obj");
$("#add").click(function(){
//obj.addClass("adder", 2000, "easeInOutCubic", onAdded);
obj.stop().addClass("adder", 2000, "easeInOutCubic", onAdded);
});
$("#remove").click(function(){
//obj.removeClass("adder", 2000, "easeInOutCubic", onRemoved);
obj.stop().removeClass("adder", 2000, "easeInOutCubic", onRemoved);
});
function onAdded () { console.log("added"); }
function onRemoved () { console.log("removed"); }
其余所有内容:http://jsfiddle.net/mmstM/42/
这似乎是一个常见的问题,但在SO或其他地方没有找到任何好的信息...请注意这是针对JQuery UI ,而不是核心。
答案 0 :(得分:7)
问题正在发生,因为即使删除了类后,为动画生成的插页式大小规则仍然存在于元素的style
属性中。
我们可以通过以下方式轻松解决这个问题:
obj.stop().attr("style", "").removeClass("adder", 2000, "easeInOutCubic", onRemoved);
但是,这会导致动画中相当大的跳跃,因为类操作的缓动不会考虑元素样式 - 这就是为什么简单地清除队列的原因没用。我担心,对此的快速解决方案非常难看:使用.animate()
方法代替,并将类中的样式移动到jQuery,如下所示:
$("#add").click(function(){
//obj.addClass("adder", 2000, "easeInOutCubic", onAdded);
obj.stop().animate({
width: '200px',
height: '80px',
}, 2000, "easeInOutCubic", onAdded);
});
$("#remove").click(function(){
//obj.removeClass("adder", 2000, "easeInOutCubic", onRemoved);
obj.stop().animate({
width: '40px',
height: '40px',
}, 2000, "easeInOutCubic", onRemoved);
});
您可以查看工作示例here,,并使用加载黑客来加载CSS中的宽度/高度值,并将它们存储在对象中以模仿add / removeClass()语法。
答案 1 :(得分:1)
问题在于,当您停止动画时,您的类不会应用于该元素。它现在处于一个意料之外的状态。因此删除该类没有任何效果,因为该类未应用于该元素。
你最好的选择是做这样的事情:
答案 2 :(得分:1)
这是我最终结束的地方:
$.fn.extend({
animateClass: function (propNames, className, speed, easing, callback) {
var $store = $("<div>").css('display', 'none').addClass(className);
$("body").append($store);
var i=0, len=propNames.length, name, propsMap={};
for (i; i<len; i++) {
name = propNames[i];
propsMap[name] = $store.css(name);
}
$store.remove();
this.stop().animate(propsMap, speed, easing, callback);
}
});
var $obj = $("#obj");
$("#bigger").click(function(){
$obj.animateClass(["width", "height"], "bigger", 2000, "easeOutQuad", function () { console.log("BIG"); });
});
具有多个状态here的工作示例。
这不是最漂亮的事情,因为它需要传递一个css属性列表才能在动画中使用,而不是只使用样式表中的所有内容,但是我找不到一种方法来分隔样式表中指定的属性。所有其他样式已经在animateClass()中创建的虚拟“$ store”div上。
我会接受@ sudowned的答案,因为这对我来说是最有帮助的。
答案 3 :(得分:1)
为什么不搜索样式表,抓住cssText,并将它解析(我不知道如何以最佳方式执行此操作)到JS对象中?
通过比较CSS规则的document.stylesheets[i].rules
成员,可以使用selectorText
数组搜索样式表。
一个同时执行这两个操作的jQuery插件是animateToSelector。
主要问题是它不灵活。我无法为一个(比如)moused over元素的孩子制作动画。理想情况下,我们应该简单地获取可以传递给animate()
这种解决方案很棒,因为jQuery-UI addClass不支持多个选择器(AFAIK)。