Javascript jQuery:单击函数bind-in for-loop with-closure-fix
我被困在这里,任何提示都很好。Javascript jQuery:单击函数bind-in for-loop with-closure-fix,javascript,jquery,arrays,object,closures,Javascript,Jquery,Arrays,Object,Closures,我被困在这里,任何提示都很好。 我有一个Objects[]数组和一个divname[]数组。我的对象上有play()和stop()等函数。对象及其功能在多种情况下进行了测试,它们正在工作。现在,我正在尝试迭代divnames[],并将相应对象[]的操作分配给mouseover、mouseout和click。 有一个关闭问题,我用在StackOverflow上的另一个线程中找到的解决方案修复了这个问题。这很有效。但剩下的问题是,mouseover等操作没有分配给稍后加载的div。他们正在处理从一开
我有一个Objects[]数组和一个divname[]数组。我的对象上有play()和stop()等函数。对象及其功能在多种情况下进行了测试,它们正在工作。现在,我正在尝试迭代divnames[],并将相应对象[]的操作分配给mouseover、mouseout和click。
有一个关闭问题,我用在StackOverflow上的另一个线程中找到的解决方案修复了这个问题。这很有效。但剩下的问题是,mouseover等操作没有分配给稍后加载的div。他们正在处理从一开始就在页面上的对象。
以下是我所拥有的:
$(function(){
for (var i=0, len=divnames.length; i<len; i++) {
if(divnames[i]){
(function( ) { // anonymous function to fix closures
var index = i; // also needed to fix closures
$('#'+divnames[index]).on("click", function() {
objects[index].play();
loadContent(divnames[index]+".php");
});
})( ); // direct function execution to fix closures
}
}
});
您需要使用事件委派,并在父元素而不是元素本身上侦听这些事件。这样,如果以后添加新元素,就不需要重新绑定它们
$("#buttons").on("click", ".button", function(){
console.log("You clicked on a .button element.");
});
在本例中,我们绑定到#buttons
上的click事件,但仅当调用元素与选择器.button
匹配时。您的标记应该是这样的:
<div id="buttons">
<a class="button">Foo</a>
<a class="button">Bar</a>
</div>
福
酒吧
当单击任何
.button
元素并冒泡到#buttons
父元素时,它将被拦截并触发处理程序。这是因为索引是在绑定语句之外声明的。当点击进入该调用时,它不知道什么是对象[index]
如果要保持相同的结构,请按如下方式重新编写函数:
$(function(){
for (var i=0, len=divnames.length; i<len; i++) {
if(divnames[i]){
(function( ) { // anonymous function to fix closures
var index = i; // also needed to fix closures
$('#'+divnames[index]).on("click", function(e) {
switch ($(e.id).attr('name')){
case 'home':
objects[0].play();
loadContent('home.php');
break;
case 'about':
// do same
case 'projects':
// do same
default:
break;
}
});
})( ); // direct function execution to fix closures
}
}
});
编辑:
当您单击div时,它只会知道以下内容:
objects[index].play();
loadContent(divnames[index]+".php");
你能分享你的两个阵列吗;这可能会帮助我们为您提供一个更好的答案。如果问题出在for循环和闭包修复结构中,为什么它可以完美地与所示的单个元素选择器配合使用?我正在尝试应用您的解决方案,但由于每个divname都有一个对象,需要独立于其他对象进行反应,这非常令人困惑。@KarlKratzisheim提供了您的数组,也许我可以为您提供一个更定制的解决方案。我添加了var index2=index;在绑定内部,并具有对象[index2].play();相反仍然不起作用,与选择器匹配的延迟加载元素没有反应。还是我误解了解决方案应该是什么样子?你误解了。此中的代码:
$('#'+divnames[index])。打开(“单击”…
是所有将被触发的内容,因此在您单击时,它周围的循环将永远不会被击中。您必须确定在适当的上下文中单击了哪个按钮。与其尝试使您的解决方案适合问题,不如将重点放在使正确的解决方案适合问题上。正确的解决方案是绑定事件,正如我在第二个代码示例。我只是想向您解释为什么它不起作用。谢谢您的帮助。我只有一个问题:如果我在click事件中放置一个简单的console.log(“hello”);即使它不需要知道任何东西,也不会显示出来。我想这是因为$('#'+divnames[index])for循环的内部永远不会知道它在单击时的索引?嗯,$('#'+divnames[index])只是一个选择器。它是一个针对dom的查询,用于选择要将单击事件绑定到的元素。因此,如果您只是使用.on('click')执行此操作,我认为它应该触发日志调用。
$(function(){
for (var i=0, len=divnames.length; i<len; i++) {
if(divnames[i]){
(function( ) { // anonymous function to fix closures
var index = i; // also needed to fix closures
$('#'+divnames[index]).on("click", function(e) {
switch ($(e.id).attr('name')){
case 'home':
objects[0].play();
loadContent('home.php');
break;
case 'about':
// do same
case 'projects':
// do same
default:
break;
}
});
})( ); // direct function execution to fix closures
}
}
});
$(document).on('click','div[name=home],div[name=projects],div[name=about]', function(){
var name = $(this).attr('name');
switch (name){
case 'home':
objects[0].play();
break;
// and so on
}
loadContent(name + '.php');
});
objects[index].play();
loadContent(divnames[index]+".php");