I can't use .children() here, It won't work since they aren't technically children. With this as my html,
<p class="l1">A</p>
<p class="l2">A1</p>
<p class="l2">A2</p>
<p class="l2">A3</p>
<p class="l2">A4</p>
<p class="l3">A41</p>
...
What I'm trying to do is slideToggle all the p.l2
elements that follow p.l1
until it reaches another p.l1
. Code folding of sorts, but without nested children. I can't figure out how to do this.
What I've got now doesn't work, seems to hang the browser. There doesn't seem to be a .descendents() function
$('p.l1').live('click', function()
{
var topobj = $(this);
var done = true;
while(done)
{
if($(topobj).next().hasClass('l2'))
{
$(topobj).next().slideToggle(100);
topobj = $(topobj).next();
}
else if($(topobj).next().hasClass('l1'))
开发者_开发知识库 done = false;
}
});
This seems to fail because it's given a single element rather than a set of elements. Don't really know how to achieve this...
You have to use nextUntil
. It'll find, from the element you've passed, the next elements until it reaches something that matches with the selector that you've passed to it.
$(".l1").click(function() {
$(this).nextUntil(".l1").toggle()
})
Demo
Please consider using nested <ul>
and <li>
.
Good luck!
nextUntil
is the traversal function you need:
$('p.l1).nextUntil('p.l1')
Sounds like you want nextAll
, which lets you grab all the following elements that match a selector. See http://api.jquery.com/nextAll/
Also, I think it's failing because your else if
should be:
else if($(topobj).next().hasClass('l3'))
// ^---- l3 instead of l1
(unless there is a typo somewhere given you said you want it to continue until finding another l1, but there isn't)
Also, see what Intelekshual posted in the comments below this about nextUntil
. That may be what you want instead.
There are two obvious ways of achieving your aim, though it'd be far easier with descendent elements.
Option one:
$('p.l1').click(
function(){
$('p.l2').slideToggle();
});
JS Fiddle demo.
Option two:
$('p.l1').click(
function(){
$(this).nextUntil('p.l3').slideToggle();
});
JS Fiddle demo.
Option three:
Trying to make it a little more generic:
$('p[class^="l"]').click(
function(){
var thisLevel = parseInt($(this).attr('class').replace('l',''), 10);
var nxtLevel = (thisLevel + 1);
$('p.l' + nxtLevel).slideToggle();
});
JS Fiddle demo.
Option four:
Slightly more generic:
$('p[class^="l"]').click(
function(){
var thisLevel = parseInt($(this).attr('class').replace('l',''), 10);
var nxtLevel = (thisLevel + 1);
var prvLevel = (thisLevel - 1);
$('p').nextUntil('p:not("p.l' + nxtLevel + '")').slideToggle();
});
JS Fiddle demo.
You have to check for l3
too. Just do !$(topobj).next().hasClass('l1')
:
http://jsfiddle.net/zeb5F/
精彩评论