如何让 jquery 精确并行执行动画? [英] How can I get jquery to execute animations in exact parallel?
本文介绍了如何让 jquery 精确并行执行动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试在 jquery 中创建一个类似于 jquery 的手风琴插件的手风琴小部件,使用我希望句柄出现在它们各自的内容下方而不是上方的区别.我的手风琴通过降低打开内容部分的高度同时增加点击内容部分的高度来工作.我在此处发布了一个示例.我的问题是动画不是在完全相同的时间开始的,并且由于第二个动画开始之前的轻微延迟,有一个明显的跳跃".
Scriptaculous 有一个名为 Effect.Parallel 的函数,它允许您创建一系列动画效果并并行执行它们.不幸的是,我似乎找不到与 jquery 类似的东西.
有没有办法在 jquery 中的单独 div 上运行精确的并行动画?
我对编写这个手风琴小部件的替代方法很感兴趣.因此,如果人们认为还有其他可行的方法,我愿意接受.
解决方案
还有一个答案,希望是最后一个...
不幸的是,John Resig 的 syncAnimate 方法不太适合我想做的手风琴式动画.虽然它在 Firefox 上运行良好,但我无法在 IE 或 Safari 上顺利运行.
话虽如此,我决定咬紧牙关,编写自己的动画引擎来执行简单的并行动画.类代码使用 jquery 函数,但不是 jquery 插件.此外,我仅将其设置为执行大小/位置动画,这正是我所需要的.
ParallelAnimations = function(animations, opts){this.init(animations, opts);};$.extend(ParallelAnimations.prototype, {选项: {持续时间:250},规则:{},初始化:函数(动画,选项){//覆盖默认选项$.extend(this.options, opts);//创建一组规则以在我们的动画中遵循for(var i 在动画中){this.rules[i] = {元素:动画[i].元素,变化:新数组()};for(var style in animations[i].styles){//计算给定样式更改的起点和终点值var from = this.parse_style_value(animations[i].element, style, "");var to = this.parse_style_value(animations[i].element, style, animations[i].styles[style]);this.rules[i].changes.push({来自:来自,到:到,风格:风格});}}this.start()},/** 对给定的和真实的样式值进行一些解析* 允许基于像素和百分比的动画*/parse_style_value:函数(元素,样式,给定值){var real_value = element.css(style);if(given_value.indexOf("px") != -1){返回 {数量: given_value.substring(0, (given_value.length - 2)),单位:px"};}if(real_value == "auto"){返回 {数量:0,单位:px"};}if(given_value.indexOf("%") != -1){var 分数 = given_value.substring(0, given_value.length - 1)/100;返回 {数量:(real_value.substring(0,real_value.length - 2)*分数),单位:px"};}如果(!给定值){返回 {数量:real_value.substring(0, real_value.length - 2),单位:px"};}},/** 开始动画*/开始:函数(){var self = this;var start_time = new Date().getTime();var freq = (1/this.options.duration);var 间隔 = setInterval(function(){var elapsed_time = new Date().getTime() - start_time;if(elapsed_time < self.options.duration){var f = elapsed_time * 频率;for(var i in self.rules){for(var j in self.rules[i].changes){self.step(self.rules[i].element, self.rules[i].changes[j], f);}}}别的{清除间隔(间隔);for(var i in self.rules){for(var j in self.rules[i].changes)self.step(self.rules[i].element, self.rules[i].changes[j], 1);}}}, 10);},/** 执行动画步骤* 仅适用于基于位置的动画*/步骤:函数(元素,变化,分数){var new_value;开关(改变.风格){案例高度":案例宽度":案例顶部":案例底部":案例左":情况正确":案例'marginTop':案例'marginBottom':案例'marginLeft':案例'marginRight':new_value = Math.round(change.from.amount - (fraction * (change.from.amount - change.to.amount))) + change.to.unit;休息;}如果(新值)element.css(change.style, new_value);}});
那么原来的 Accordion 类只需要在 animate 方法中进行修改就可以使用新的调用了.
Accordion = function(container_id, options){this.init(container_id, options);}$.extend(Accordion.prototype, {容器 ID: '',选项: {},活动标签:0,动画:假,button_position: '下面',持续时间:250,高度:100,handle_class: ".handle",section_class: ".section",初始化:函数(container_id,选项){var self = this;this.container_id = container_id;this.button_position = this.get_button_position();//每个部分的高度,如果可能,使用样式表中指定的高度this.height = $(this.container_id + " " + this.section_class).css("height");if(options && options.duration) this.duration = options.duration;if(options && options.active_tab) this.active_tab = options.active_tab;//将第一部分设置为具有高度并打开"//所有其余部分的高度应为 0px$(this.container_id).children(this.section_class).eq(this.active_tab).addClass("打开").css("高度", this.height).siblings(this.section_class).css("高度", "0px");//找出句柄的状态this.do_handle_logic($(this.container_id).children(this.handle_class).eq(this.active_tab));//设置一个事件处理程序来为每个部分设置动画$(this.container_id + " " + this.handle_class).mouseover(function(){如果(自我动画)返回;self.animate($(this));});},/** 确定句柄是在其关联部分的上方还是下方*/获取按钮位置:函数(){return ($(this.container_id).children(":first").hasClass(this.handle_class) ? 'above' : 'below');},/** 将手风琴从一个节点动画到另一个节点*/动画:函数(句柄){var active_section = (this.button_position == 'below' ? handle.prev() : handle.next());var open_section = handle.siblings().andSelf().filter(".open");如果(active_section.hasClass(打开"))返回;this.animating = true;//找出句柄的状态this.do_handle_logic(handle);//关闭打开的部分var arr = new Array();arr.push({元素:open_section,样式:{高度":0px"}});arr.push({元素:active_section,样式:{高度":this.height}});新的 ParallelAnimations(arr, {duration: this.duration});var self = this;window.setTimeout(function(){open_section.removeClass("打开");active_section.addClass("打开");self.animating = false;}, this.duration);},/** 更新每个句柄的当前类或状态"*/do_handle_logic:函数(句柄){var all_handles = handle.siblings(".handle").andSelf();var above_handles = handle.prevAll(this.handle_class);var below_handles = handle.nextAll(this.handle_class);//删除所有过时的句柄all_handles.removeClass("handle_on_above").removeClass("handle_on_below").removeClass("handle_off_below").removeClass("handle_off_above");//将on"状态应用到当前句柄if(this.button_position == '下面'){处理.addClass("handle_on_below");}别的{处理.addClass("handle_on_above");}//将关闭上方/下方状态应用于其余的句柄上面_句柄.addClass("handle_off_above");下面_句柄.addClass("handle_off_below");}});
HTML 的调用方式仍然相同:
<头><title>平行手风琴动画</title><script type="text/javascript" src="jquery.js"></script><script type="text/javascript" src="ui.js"></script><script type="text/javascript">$(document).ready(function(){新手风琴(#accordion");});<style type="text/css">#手风琴{位置:相对;}#手风琴.句柄{宽度:260px;高度:30px;背景颜色:橙色;}#手风琴.section{宽度:260px;高度:445px;背景颜色:#a9a9a9;溢出:隐藏;位置:相对;}</风格>头部><身体><div id="手风琴"><div class="section"><!-- --></div><div class="handle">handle 1</div><div class="section"><!-- --></div><div class="handle">handle 2</div><div class="section"><!-- --></div><div class="handle">handle 3</div><div class="section"><!-- --></div><div class="handle">handle 4</div><div class="section"><!-- --></div><div class="handle">handle 5</div>