How do I access a sub-element when using $(this) in jQuery - javascript

I have the following code:
$(document).ready(function(){
$(document).on('click', '.mydiv', function(){
console.log(??????);
});
});
I also have the corresponding html
<div class="mydiv">
<p>Hello from inside a mydiv</p>
</div>
<div class="mydiv">
<p>Hello from inside some other mydiv</p>
</div>
My goal is to print the text inside the p tags to the console when the I click on any div with the class of mydiv. I know that this means I should be using the $(this) operator, but when I do that I am unsure of how to then access its sub elements.
I know if I were using id's (or if I only had one of these class objects) I could simply do $('#mydiv p').val(), but I'm unsure of how to achieve this when I'm using $(this).

You can use $('p',this) or $(this).find('p') to get p tag element in this context:
$(document).on('click', '.mydiv', function(){
console.log($('p',this).text());
});
Working Demo

Using $(this) and jQuery's .find() you can get the child elements that you choose:
console.log($(this).find('p').html());

There are multiple ways to go about this. One of the ways has been mentioned here by others (the find method). The problem with the find method is that it finds all elements inside your div and not the direct children. So, if you have elements that are nested another level, it gets that as well.
With the children method, it will find the direct child of the element, but not anything nested deeper.
<div class="mydiv">
<div>
<p>Nested p</p>
</div>
</div>
$('.mydiv').find('p'); // Finds this element, but children() will not
Versus
<div class="mydiv">
<p>
Direct p
</p>
</div>
$('.mydiv').children('p'); // Will find this element, but find() will as well
With the find method, you will find the one nested inside the second div, whilst with the children method, you will find only the direct child.
Depending on your needs, you may use find or children

Related

Using jQuery to find a html element in a parallel tree path

Let's say I have this piece of html:
<div>
<a class="target"/>
<div>
<a class="target"/>
<div>
<hr class="source"/>
</div>
</div>
</div>
I'd like to find the closest target from the source, meaning the one where I need to climb the fewest amount of parents. With a binding, I get the source element, that I'll note source. I want to find the second anchor, which is two levels deep, as it's closer to my source hr.
Here's what I have right now is, which works:
var target = source
.parentsUntil(".target").eq(0)
.find(".target")[0];
It seems rather uneffective though, because parentsUntil will test and return too many of the parents. I'd like it to stop on the first parent containing a .target element. Then I feel like calling find after makes jQuery look for target once more while it had already found it before with parentsUntil.
I can think of another solution that would involve iterating over source.parents() and calling find until I have a result but that would still search into branches that have already been explored.
Is there a function in jQuery or a custom algorithm I could leverage to get my result by exploring only the part of the tree that needs to be explored?
I'd suggest:
// starts at the element(s) with the class of
// 'source':
$('.source')
// finds the closest <div> element that contains
// an <a> element with the class-name of 'target':
.closest('div:has("a.target")')
// finds that contained <a> element with
// the class of 'target':
.find('a.target');
$('.source').closest('div:has("a.target")').find('a.target').addClass('found');
a::before {
content: attr(class);
}
.found {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<a class="target"></a>
<div>
<a class="target"></a>
<div>
<hr class="source" />
</div>
</div>
</div>
References:
addClass().
closest().
find().
:has() selector.
In your case you can use .parent() to select the parent div of .source element and use .prev() to get the previous element which is <a> in your case
$('.source').parent().prev()
or you can use
$('.source').parent().parent().find('a.target')

How to look for a parent element which contains a specific selector

Let's suppose to have the following html structure (1).
From $('.child') element I can access the $('.gran-parent') element making something like $('.child').parent().parent();.
Anyway I don't think this is a good way because is not generic.
Let's suppose there are other divs between $('.gran-parent') and $('.child').
What is the most generic way to refers to the first parent which class is gran-parent, starting from $('.child') ?
<div class='gran-parent'>
<div class='parent'>
<div class='child'>
</div>
</div>
</div>
You want:
$('.child').closest(".grand-parent");
.closest will keep traversing up until it finds a .grand-parent. You can also do .parents(".grand-parent") but that could return more than one result, depending on your DOM hierarchy, so you would have to do:
.parents(".grand-parent").eq(0)
or:
.parents(".grand-parent").slice(0)
or:
.parents(".grand-parent:first")
all of which are less elegant than .closest().
See:
http://api.jquery.com/closest/
http://api.jquery.com/parents/
You're looking for the .parents() operator.
Example:
$('.child').parents('.gran-parent');

closests jquery

<div class="panels">
<div>
<h2>
Test
</h2>
</div>
<div class="inner_panel statict">
Test2
</div>
</div>
I want so that when people click on Test, Test2 appears. If not, they don't see Test2, How can I make that happen using jquery?
I tried the following but it does not work.
$('.inner_panel').hide();
$('.panels').click(function () {
$(this).closest('div .inner_panel').toggle();
});
I have multiple divs with class panels in the file, so I don't want click on Test affecting the other "panels."
closest method looks up in the DOM tree, not down. You can check it here. http://api.jquery.com/closest/
Maybe you should use .children('div.inner_panel') to get your element. children method allows you to get elements, that are a single level down the DOM. Check http://api.jquery.com/children/ fo details.
You have an extra space -> $(this).closest('div .inner_panel').toggle();
This should be: $(this).closest('div.inner_panel').toggle();
But .closest() is not going to work for you because it travels up the DOM tree and not up and then down to siblings etc.
I would do this:
$('.inner_panel').hide();
$('.panels').click(function () {
$(this).find('div.inner_panel').toggle();
});
See jsbin demo
$('.inner_panel').hide();
// Within .panels get the div's which contain an H2
var containers = $('.panels h2').closest("div");
// make them clickable
containers.click(function () {
// For the clicked panel, get the next element div which
// has the inner_panel class
$(this).next('div.inner_panel').toggle();
});

Find the first parent of a selector

Consider this sample html
<div class="A">
<div class="B">
<span class="C">Sample text</span>
<div class="D">
<div class="E">Clickable Text</div>
</div>
</div>
</div>
And some jQuery
$(".E").click(function(){
//body
});
What is the easiest way to get a parent of $(this) that matches a selector? For example, say in the example I need to get the div where class="A". At the moment because I know the structure of the html I could do
$(this).parent().parent();
But I'm looking for a way that would work regardless of the structure. Something along the lines of
$(this).findFirstParent(".A");
I hope I've been understandable.
$(".E").click(function(){
console.log($(this).closest('.A'));
/* console.log($(this).parents('.A')); works fine too */
});
See
http://api.jquery.com/closest/
http://api.jquery.com/parents/
Note that parent() is different than parents() method (the first one look for one ancestor only)
First Solution:
$(this).closest('.A')
Source: http://api.jquery.com/closest/
This will return the first parent when traversing that matchs the selector.
Second solution:
$(this).parents('.A:first')
Source: http://api.jquery.com/parents/
This will return all the parents that matches the selectors
What about
$(this).closest(".A");
This is the way i would do it
$(this).parents("div.A")
The jQuery parent selector might help you there. You can combine it with the class you are looking for. See the docs #
http://api.jquery.com/parent-selector/

Jquery find all except

I have following HTML:
<div id="123" class="test">
<div class="testMessage">Foo</div>
<div><div class="testDate">2010</div></div>
<div id="127" class="test">
<div class="testMessage">Bar</div>
<div><div class="testDate">2011</div></div>
</div>
</div>
And I have following JS/jQuery code:
$(".test").find(".testDate").val("cool 2010");
How to change JS/jQuery to find "testDate" class element except in children "test" class block without using children?
P.S. I know only about class name and I don't know how many divs can be nested.
Update
Its probably the weirdest selector I've ever written:
$("div.test").not(':has(> .test)').siblings().find('.testDate').text('cool 2010');
Demo: http://jsfiddle.net/mrchief/6cbdu/3/
Explanation:
$("div.test") // finds both the test divs
.not(':has(> .test)') // finds the inner test div
.siblings() // get all other divs except the inner test div
Try this and also div elements do not have a value property, use html() method to set the inner html or text()
$("div.test :not(.test)").find(".testDate").html("cool 2010");
If you can modify your main div id to "_123", you can straight away use the id selector like this
$("#_123 > div.testDate").html("cool 2010");
I think the not() selector might help. You can learn more about it here: http://jsperf.com/jquery-css3-not-vs-not
Anytime you try to select $('.test'), it will grab all elements with a class='test'. You need to start at the outermost body tag:
$('body').children('.test').children(':not(.test)').find('.testDate').text('cool 2010');

Categories

Resources