jQuery 中的连锁效应
我正在编写一个具有以下标记菜单的网站:
<div id="grafico-wrapper">
<h2>Gráfico</h2>
<ul id="grafico-categories" class="categories-menu">
<li><a href="#" rel="cat1">Category1</a></li>
<li><a href="#" rel="cat2">Category2</a></li>
<li><a href="#" rel="cat3">Category3</a></li>
</ul>
<ul id="grafico-projects" class="projects-menu">
<li><a href="#" class="slider-link" rel="cat2,cat1">Project1</a></li>
<li><a href="#" class="slider-link" rel="cat2,cat1">Project2</a></li>
<li><a href="#" class="slider-link" rel="cat1">Project3</a></li>
<li><a href="#" class="slider-link" rel="cat2">Project4</a></li>
<li><a href="#" class="slider-link" rel="cat1,cat3">Project5</a></li>
<li><a href="#" class="slider-link" rel="cat1">Project6</a></li>
<li><a href="#" class="slider-link" rel="cat3">Project7</a></li>
</ul>
</div>
<div id="producto-wrapper">
<h2>Producto</h2>
<ul id="producto-categories" class="categories-menu">
<li><a href="#" rel="cat1">Category1</a></li>
<li><a href="#" rel="cat2">Category2</a></li>
<li><a href="#" rel="cat3">Category3</a></li>
</ul>
<ul id="producto-projects" class="projects-menu">
<li><a href="#" class="slider-link" rel="cat2,cat1">Project1</a></li>
<li><a href="#" class="slider-link" rel="cat1,cat3">Project2</a></li>
<li><a href="#" class="slider-link" rel="cat1">Project3</a></li>
<li><a href="#" class="slider-link" rel="cat2,cat3">Project4</a></li>
<li><a href="#" class="slider-link" rel="cat2">Project5</a></li>
<li><a href="#" class="slider-link" rel="cat3">Project6</a></li>
</ul>
</div>
基本上有 2 个主要类别(“grafico”和“producto”),每个类别都有其子类别(ul.categories-menu
)及其项目 (ul.projects-menu
)。
此外,每个子类别在 rel
属性中都有一种“id”,每个项目在 rel
属性中都有一个以逗号分隔的子类别列表。它所属的类别。
所以,我想要实现的是,当单击子类别链接时,该类别的所有项目在其 rel
中包含子类别 rel
值都会得到“突出显示”(变成另一种颜色),但是以“级联”方式(从上到下,项目将改变其颜色),之后,当单击另一个子类别链接时,所有项目都会变成到原始颜色,并且突出显示级联再次从属于新单击的子类别的项目开始。
我还使用 xcolor 插件来允许 animate()
函数可以平滑地改变高光的颜色。
到目前为止,这是我的(简化的)代码:
highlight: function(elem) {
//clear previous highlights
this.clearHighlight();
elem = $(elem);
var rel = elem.attr('rel');
var highlight_color = '#6666F0';
var highlightSpeed = 400;
var highlightDelay = 100;
//we highlight the sub-category element
elem.animate({color: highlight_color}, highlightSpeed).addClass('highlighted');
//we find the projects matching the rel attribute and we highlight them
elem.parents('ul.categories-menu')
.nextAll('ul.projects-menu')
.find('a[rel*=' + rel + ']')
.each(function(i, elem) {
$(elem).delay(i * highlightDelay).animate({color: highlight_color}, highlightSpeed).addClass('highlighted');
});
},
clearHighlight: function() {
var defColor = '#BABABA';
var highlightSpeed = 400;
$('#menu').animate({color: defColor}, highlightSpeed).removeClass('highlighted');
}
该代码运行得很好,但“级联”效果并不完全起作用,例如:当项目 1、3、4 和 6 突出显示时(第一个级联效果很好),然后您单击另一个应突出显示项目 1、4、5 和 6 的子类别(注意 1 和 4 是常见的),
- 我想要的是:所有项目都设置回默认颜色,然后是项目 1、4、5 和 6 是
- 我得到的是:所有项目都设置回默认颜色,然后项目 5、6、1 和 4 一个接一个地突出显示,并且有一点延迟(1 和 4 稍后突出显示,因为他们首先需要一些时间才能恢复到旧状态)
我希望我可以解释我的问题,有人可以指出我正确的方向来解决这个小问题吗?
谢谢
I'm coding a website that has a menu with this markup:
<div id="grafico-wrapper">
<h2>Gráfico</h2>
<ul id="grafico-categories" class="categories-menu">
<li><a href="#" rel="cat1">Category1</a></li>
<li><a href="#" rel="cat2">Category2</a></li>
<li><a href="#" rel="cat3">Category3</a></li>
</ul>
<ul id="grafico-projects" class="projects-menu">
<li><a href="#" class="slider-link" rel="cat2,cat1">Project1</a></li>
<li><a href="#" class="slider-link" rel="cat2,cat1">Project2</a></li>
<li><a href="#" class="slider-link" rel="cat1">Project3</a></li>
<li><a href="#" class="slider-link" rel="cat2">Project4</a></li>
<li><a href="#" class="slider-link" rel="cat1,cat3">Project5</a></li>
<li><a href="#" class="slider-link" rel="cat1">Project6</a></li>
<li><a href="#" class="slider-link" rel="cat3">Project7</a></li>
</ul>
</div>
<div id="producto-wrapper">
<h2>Producto</h2>
<ul id="producto-categories" class="categories-menu">
<li><a href="#" rel="cat1">Category1</a></li>
<li><a href="#" rel="cat2">Category2</a></li>
<li><a href="#" rel="cat3">Category3</a></li>
</ul>
<ul id="producto-projects" class="projects-menu">
<li><a href="#" class="slider-link" rel="cat2,cat1">Project1</a></li>
<li><a href="#" class="slider-link" rel="cat1,cat3">Project2</a></li>
<li><a href="#" class="slider-link" rel="cat1">Project3</a></li>
<li><a href="#" class="slider-link" rel="cat2,cat3">Project4</a></li>
<li><a href="#" class="slider-link" rel="cat2">Project5</a></li>
<li><a href="#" class="slider-link" rel="cat3">Project6</a></li>
</ul>
</div>
Basically 2 main categories ("grafico" and "producto") each one with its sub-categories (ul.categories-menu
) and its projects (ul.projects-menu
).
Also each one of the sub-categories has a sort of "id" in the rel
attribute and each project has in the rel
attribute a comma-separated list of the sub-categories it belongs to.
So, what I want to achieve is that, when clicking a sub-category link, all the projects of this category containing in its rel
the sub-category rel
value get "highlighted" (turned into another color), but in a "cascade" fashion (from up to down, the projects will be changing their color), and when, after that, another sub-category link is clicked, all the projects will turn to the original color, and the highlight cascade starts again with the projects belonging to the new clicked sub-category.
I'm also using the xcolor plugin to allow the animate()
function to do a smooth change of color for the highlights.
This is my (simplified) code so far:
highlight: function(elem) {
//clear previous highlights
this.clearHighlight();
elem = $(elem);
var rel = elem.attr('rel');
var highlight_color = '#6666F0';
var highlightSpeed = 400;
var highlightDelay = 100;
//we highlight the sub-category element
elem.animate({color: highlight_color}, highlightSpeed).addClass('highlighted');
//we find the projects matching the rel attribute and we highlight them
elem.parents('ul.categories-menu')
.nextAll('ul.projects-menu')
.find('a[rel*=' + rel + ']')
.each(function(i, elem) {
$(elem).delay(i * highlightDelay).animate({color: highlight_color}, highlightSpeed).addClass('highlighted');
});
},
clearHighlight: function() {
var defColor = '#BABABA';
var highlightSpeed = 400;
$('#menu').animate({color: defColor}, highlightSpeed).removeClass('highlighted');
}
This code works quite well, but the "cascade" effect is not totally working, for example: when projects 1, 3, 4 and 6 are highlighted (first cascade works nice) and then you click another sub-category that should highlight projects 1, 4, 5 and 6 (note 1 and 4 are common),
- what I want is: all projects are set back to their default color, and then projects 1, 4, 5 and 6 are highlighted one after the other with the little delay
- what I get is: all projects are set back to their default color, and then projects 5, 6, 1 and 4 are highlighted one after the other with the little delay (1 and 4 are highlighted later because they first take some time getting back to the old state)
I hope I explained my problem ok, can someone point me in the right direction to solve this little issue?
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 jQuery 的每个动画中,您都可以指定一个成功处理程序。
在我看来你需要等待 1 & 4 要在触发新动画之前重置,您可以通过 1 & 的重置动画的成功处理程序来执行此操作。 4. 这会延迟启动新动画,这可能会让用户感到厌烦,因为界面会感觉迟缓。
更好的方法可能是为 1 & 制作动画。 4 直接从它们拥有的任何颜色到新的颜色,而不是先重置它们,即。仅重置 3 & 6 因为它们不需要立即再次设置动画。
您也可以只为 3 和 3 的重置设置动画。 6、直接复位1&; 4 因此他们准备立即为新颜色设置动画 - 因为他们将设置动画,因此重置是否设置动画可能并不重要,但这是 UI 设计的决定。
更新:
如果您正在运行多个动画(您应该尽量避免)并且只希望在所有动画完成后启动新的动画集,只需记下正在运行的动画和未运行的动画即可。
您可以通过多种方式执行此操作:
手动保持计数:每次启动动画时增加计数器,每次结束动画时减少计数器 - 在成功处理程序中,减少计数检查零计数并启动新动画。 CaveAt:这里可能存在竞争条件,但可以稍微小心地处理:)
轮询 jQuery效果队列来查看动画是否仍在运行 - 这有一定的开销,如果您不小心,可能会使您的动画变得迟缓(但如果您不采取措施,所有动画都注定会缓慢且迟缓)注意 - 多个并行运行的动画通常对性能来说是一个坏主意)
In every animation in jQuery you can specify a success handler.
Seems to me you need to wait for 1 & 4 to be reset before triggering the new animation, you can do this through the success handler of the reset-animation for 1 & 4. This will give a delay for starting the new animation tho, and that can become annoying for the user since the interface will feel laggy.
A better way would probably be to animate 1 & 4 directly from whatever color they have to the new one, instead of resetting them first, ie. only reset 3 & 6 since they don't need to animate again right away.
You could also only animate the reset of 3 & 6, and the directly reset 1 & 4 so they are ready to animate to the new color right away - since they will be animating it might not matter if the reset is animated, but that is a ui-design decision.
Update:
In the case where you have multiple animations running (which you should try to avoid) and only wish to start the new set of animations when they all are finished, just keep count on what is running and what isn't.
You can do this multiple ways:
keep count manually: increase a counter everytime you start an animation and decrease it everytime you end one - in the successhandler that decreases the count check for zero count and start the new animations. CaveAt: there is a possible racecondition here, but that can be handled with a little care :)
poll the jQuery effects queue to see if animations are still running - this has a certain overhead that can make your animations laggy if you don't take care (but then all animations are doomed to be slow and laggy if you don't take care - multiple parallel running animation are generally a bad idea for performance)