Reputation: 4162
I'm trying to learn how to use jQuery's closest() and filter() methods. closest() traverses up the DOM tree while filter() traverses down.
In the following code, after a user clicks the link, jQuery should search up the DOM until it finds the "row" class, search down until it finds the "test" class then return the text in that element. Why is console log printing blank instead of "Hello?"
$('.button').on('click', function(e) {
console.log( $(this).closest('.row').filter('.test').text() );
e.preventDefault();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr class="row">
<td><span class="test">Hello</span>
<table>
<tr>
<td><a class="button" href="#">Button 1</a></td>
</tr>
</table>
</td>
</tr>
</table>
Upvotes: 1
Views: 1144
Reputation: 7878
You are mixing up filter()
and find()
filter()
Reduce the set of matched elements to those that match the selector
This will not return anything because closest('.row')
does not contain an element with .test
find()
Get the descendants of each element in the current set of matched elements
Searches for .test
down the DOM starting at the element returned by closest('.row')
$('.button').on('click', function(e) {
console.log($(this).closest('.row').find('.test').text());
e.preventDefault();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr class="row">
<td><span class="test">Hello</span>
<table>
<tr>
<td><a class="button" href="#">Button 1</a></td>
</tr>
</table>
</td>
</tr>
</table>
When you really want to use filter()
instead if find()
you could do something like this:
$('.button').on('click', function(e) {
var text;
$(this).closest('.row').filter(function(){
text = $( ".test", this ).text();
return $( ".test", this ).length === 1;
});
console.log(text);
e.preventDefault();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr class="row">
<td><span class="test">Hello</span>
<table>
<tr>
<td><a class="button" href="#">Button 1</a></td>
</tr>
</table>
</td>
</tr>
</table>
But I would not recommend this as it defies the purpose of having a dedicated function for that.
Upvotes: 2
Reputation: 6040
So basically you misunderstood what filter()
does. From what you say you're wanting to do you should use find()
instead.
<table>
<tr class="row">
<td><span class="test">Hello</span>
<table>
<tr>
<td><a class="button" href="#">Button 1</a></td>
</tr>
</table>
</td>
</tr>
</table>
$(document).ready(function() {
$('.button').on('click', function(e) {
console.log($(this).closest('.row').find('.test').text());
e.preventDefault();
});
});
Fiddle for you to play around.
To clarify here's what filter()
does:
Reduce the set of matched elements to those that match the selector or pass the function's test.
So in you original code - your matched element is the .row
element. You're trying to reduce that to elements that has test
as a class as well.
Upvotes: 3