问题
I am looping around span elements which belongs to frag
class. I wanted to detect if the frag element im currently in is the youngest son/grandson/grandgrand son(from left to right) of the a span element which belongs to frag
class and belongs to cond
class and has an "if" or "else if" in its text
contenteditable div (textarea)
if( ((b>0) && (b<10)) || b==15 )
HTML equivalent
<div id="board">
<div>
<span class="frag cond">if<span class="openParen bm1">(</span> <span class="frag cond"><span class="openParen bm2">(</span><span class="frag cond"><span class="openParen bm3">(</span><span class="frag">b</span>>0<span class="closeParen bm3">)</span></span> && <span class="frag cond"><span class="openParen bm4">(</span><span class="frag">b</span><10<span class="closeParen bm4">)</span></span><span class="closeParen bm2">)</span></span> || <span class="frag">b</span>==15 <span class="closeParen bm1">)</span></span>
</div>
</div>
(My system is like a code editor by the way, so i am using a contenteditable div) Here, i wanted to detect if im on the 3rd b
.
byossarian has helped me with this:
var $elem = $('.frag').eq(fragNum);
var validAncest = $elem.parents('.cond').filter(function(i){
return /^\s*(if|else\s+if)/.test($(this).text());
}).filter(function(i){
var generations = 0,
$elemCrawl = $('.frag').eq(fragNum);
while ($elemCrawl[0] && $elemCrawl[0] !== this) {
generations++;
$elemCrawl = $elemCrawl.parent();
}
if ($elemCrawl[0] && generations < 4) {
return true;
}
});
finds all the ancestors of the element, it then filters then once to narrow down to those starting with 'if' or 'else if'. It then filters these to those that are either the parent, grandparent or great-grandparent (generations < 4) of the original element.
the condition to check will be:
if (validAncest.length && !$elem.nextAll('.frag').length) {
alert('target acquired');
}
It checks that there is at least one valid ancestor (validAncest.length) AND that the original element is the last child of it's IMMEDIATE parent that has the class 'frag' (!$elem.nextAll('.frag').length)
The problem
IMMEDIATE parent should also be the last child/grandchild of the element with "if" or "else if"
So from the example above, the first b
will already give me the alert where it should be on the 3rd b
UPDATE should pop the alert at the 2nd b
not at (b<10)
回答1:
Try changing validAncest
with:
var validAncest = $elem.parents('.cond').filter(function(i){
return /^\s*(if|else\s+if)/.test($(this).text());
}).filter(function(i){
var generations = 1,
$elemCrawl = $('.frag').eq(fragNum).parent();
while ($elemCrawl[0] && $elemCrawl[0] !== this) {
if (!$elemCrawl.is(':last-child')) {return false;}
generations++;
$elemCrawl = $elemCrawl.parent();
}
if ($elemCrawl[0] && generations < 4) {
return true;
}
});
This should include:
- The parent of $elem provided it starts with 'if'/'else if'
- The grandparent provided it starts with 'if'/'else if' AND the parent of $elem is the last child of this grandparent
- The great-grandparent provided it starts with 'if'/'else if' AND the parent of $elem is the last child of the intermediate grandparent AND that grandparent is the last child of the great-grandparent
来源:https://stackoverflow.com/questions/18864758/detect-if-the-element-im-currently-in-is-the-youngest-son-grandson-grandgrand-so