我会尽量保持这一点。我正在尝试创建用户单击展开按钮时隐藏或显示的文本框。我正在使用toggle()方法。
标记是这样的:
<span id="toggle0">+</span>
<div id="toggle0Container">
blablabla...
<div>
<span id="toggle1">+</span>
<div id="toggle1Container">
blablabla...
<div>
<span id="toggle2">+</span>
<div id="toggle2Container">
blablabla...
<div>
// etc
#togle0应该切换#togle0Container,#toggle1切换#topggle1Container,依此类推。这全部由PHP生成,因此可以有任意数量的这些容器。
这是JQuery代码:
$(document).ready(function() {
// array of numbers, it's pretty redundant, there will never be more than 30 containers
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9 , 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36];
// hide all containers first
jQuery.each(arr, function() {
$('#toggle' + this + 'Container').hide();
});
// now the toggle buttons
jQuery.each(arr, function() {
$('#toggle' + this).click(function() {
// this line is not working
$('#toggle' + this + 'Container').slideToggle('slow');
// and this just changes the toggle button from + to -
if ($(this).html() == '+') {
$(this).html('-');
} else {
$(this).html('+');
}
});
});
});
除了切换部分之外它是有效的(我在不起作用的行上方添加了注释)。问题出在哪里?
答案 0 :(得分:5)
这是因为“this”现在处于不同的范围,并且指的是实际的#toggleN DOM元素,而不是数组中的一个数字。
我建议你抛弃数字数组,然后使用不同的选择器,例如:
$("div[id^=toggle][id$=container]").hide();
$("span[id^=toggle]").click(function() {
$(this).find("span[id^=toggle][id$=container]").slideToggle("slow");
// .. do your other html stuff
}
放弃那些每个人并用那些替换切换选择器。
答案 1 :(得分:2)
修改强>
我更喜欢针对您的特定用例的mgroves解决方案,但我会留下我的答案,这解释了如何接受索引和元素作为.each方法的参数
原始回答
正如其他人所说, this 的上下文并不是您所认为的那样。这是雷米夏普的一篇很棒的文章,标题为“jQuery's this: demystified”,我建议你阅读。
.each函数可以接受两个极大帮助你的参数,你不需要那个数组。
$('span[id^=toggle']').each(function(idx, elem) {
// idx is the current index of the jQuery object
$('#toggle' + idx).click(function() {
// elem is the current element
$(elem).next('#toggle' + idx + 'Container').slideToggle('slow');
if ($(elem).html() == '+') {
$(elem).html('-');
} else {
$(elem).html('+');
}
});
});
答案 2 :(得分:2)
我会遵循mgroves的方法但是如果你真的想做数组的事情,或者只是想弄清楚如何正确使用每个(),那么你应该如何使用它:
$(document).ready(function() {
// array of numbers, it's pretty redundant, there will never be more than 30 containers
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9 , 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36];
// hide all containers first
jQuery.each(arr, function(index, item) {
$('#toggle' + item + 'Container').hide();
});
// now the toggle buttons
jQuery.each(arr, function(index, item) {
$('#toggle' + item).click(function() {
// this line is not working
$('#toggle' + item + 'Container').slideToggle('slow');
// and this just changes the toggle button from + to -
if ($(this).html() == '+') {
$(this).html('-');
} else {
$(this).html('+');
}
});
});
});
答案 3 :(得分:1)
我建议在您的切换按钮(span)上添加一个类,如“toggler”和您的切换容器,如“容器”或其他东西,以简化您的javascript:
$(function() {
// hide all containers first
$(".container").hide();
// now the toggle buttons
$(".toggler").click(function() {
var container = $("#" + $(this).attr("id") + "Container");
container.slideToggle("slow");
$(this).html(container.is(":visible") ? "-" : "+");
});
});
试一试。
答案 4 :(得分:1)
正如mgroves所说,你的范围是通过使用每个()来解决所有问题。有关详细信息,请参阅this。
答案 5 :(得分:1)
我准备发布Max对使用课程的确切意见。我只会通过这个更容易的选择器来改进他的建议来找到容器:
$(function() {
// hide all containers first
$(".container").hide();
// now the toggle buttons
$(".toggler").click(function() {
$(this).next().slideToggle("slow");
if (container.is(":visible")) {
$(this).html("-");
}
else {
$(this).html("+");
}
});
});
如果您无法轻松获取跨度上的类,则可以使用$('#SpanContainer&gt; span')之类的东西构建类似的选择器,以按标记名称选择它们,从其包含元素开始。
答案 6 :(得分:0)
我最近为这样的行为写了一个相当实质的脚本。我选择了一个稍微不同的路线,因为我选择将一个给定的hide / show元素的所有元素包含在一个包含的div中。如果需要,它允许您为一个部分设置多个“触发器”,并且可以添加任意数量的隐藏/显示元素,而无需担心编号。我会把它构造成这样的东西:
<div class="expSecWrapper">
<div class="expSecTrigger">Insert Trigger Here</div>
<div class="expSecBody">
Content to hide/show
</div>
</div>
然后jQuery代码将是这样的:
$(document).ready(function(){
var targets = $(".expSecWrapper")
targets.find(".expSecTrigger").click(function(){
targets.find(".expSecBody").hide()
$(this).parents(".expSecWrapper").eq(0).children(".expSecBody").toggle();
})
})
您可以为您的应用添加剩余的相关JS。
它有一些限制,例如隐藏/显示主体是包装器的直接后代的必要性。它可以应用于下拉菜单,单选按钮等等。它也可以嵌套,因此如果隐藏/显示你可以有多个级别。
最后一件事是你实际上甚至不需要使用.each迭代器来分配该行为。像.click()这样的东西会将行为分配给整个jQuery对象组。只要你使用一个能够抓住你所有目标的选择器。
抱歉,不得不编辑几次。
答案 7 :(得分:0)
您应该为您的元素提供可以搜索的类,然后使用next
。
使你的标记像这样:
<span class="toggleButton">+</span>
<div class="toggleContainer">
blablabla...
<div>
现在,处理此问题的代码变得如此简单:
$('.toggleButton').click(function() {
$(this).next('.toggleContainer').slideToggle('slow');
});