我正在尝试为文档创建一个手风琴效果,当您单击<h1>
文档的其余部分(<div.container>
)时,切换向下滑动并向下滑动。然而,我一直遇到问题。这是代码:
HTML
<article>
<h1>Title</h1>
<div class="container">
//...
</div>
</article>
<article>
//...
</article>
<article>
//...
</article>
CoffeeScript的:
articles = $('article').toArray()
for article in articles
#console.log $('.container', article).parent().attr('id')
$('h1', article).click ->
$('.container', article).slideToggle 'slow'
当我使用article
变量时... console.log
它会旋转文章并打印回来的ID。但是当我点击任意<h1>
个元素时,它总是会折叠最后<article>
个<div.container>
。
我认为这是因为article
变量存储在CoffeeScript中for
循环范围之外,并且直到循环完成后才会执行单击。
如果是这样,如何保证在执行点击事件时引用正确的对象?使用for i in [0...3]
循环并直接引用数组会更好吗?问题完全不同吗?谢谢你的帮助!
对于那些可能不熟悉coffeeScript的人,这里是编译的javaScript(只是忽略_results变量):
var articles
articles = $('article').toArray();
_results = [];
for (_i = 0, _len = articles.length; _i < _len; _i++) {
article = articles[_i];
_results.push($('h1', article).click(function() {
return $('.container', article).slideToggle('slow');
}));
}
答案 0 :(得分:3)
您看到此行为的原因是因为article
事件中引用的click
在触发处理程序之前不会被评估,并且在该时间点,它被设置为上一篇文章这是在你的循环中评估的。
这可能会对你有所帮助(对不起,不确定咖啡脚本的实现):
$('article h1').click(function() {
$(this).next('.container').slideToggle('slow');
});
答案 1 :(得分:2)
Rocco的回答是正确的。让我扩展它:
这是一个常见的混淆区域:只有函数在JavaScript(和CoffeeScript)中创建范围,这意味着当您在循环中执行异步操作时,您必须记住“捕获”变量。在CoffeeScript中执行此操作的首选方法是使用do
语法,可以编写
for article in articles
do (article) ->
$('h1', article).click ->
$('.container', article).slideToggle 'slow'
编译为相当于
for article in articles
((article) ->
$('h1', article).click ->
$('.container', article).slideToggle 'slow'
)(article)
这样,每个click
回调都会看到自己的article
迭代,而不是在循环时改变值的迭代。我在PragPub文章A CoffeeScript Intervention中简要地讨论了这个问题。
答案 2 :(得分:1)
这是另一种方法(在javascript / jQuery中):
this.parentNode
从点击.container
对象。 这样,我们不必在点击中存储任何状态,因为我们可以找到与点击的项目共享同一父节点的容器。此方法也不依赖于容器对象相对于单击的h1的确切位置 - 它只需要容器共享同一个父级,以便在将来的布局中更灵活。
$('article h1').click(function() {
$('.container', this.parentNode).slideToggle('slow');
});
答案 3 :(得分:0)
我对Coffeescript一无所知,但编译好的Javascript有一个非常明显的错误。
这一行:
article = articles[_i];
应该是这样的:
var article = articles[_i];
通过此更改,article变量将被视为调用范围的一部分,并在调用处理程序时引用相应的元素(而不是引用隐式全局变量)。这就是修复错误所需的一切。
希望有一种方法可以在Coffeescript中指定,但是文章中的文章不会自动执行此操作似乎非常可怕。