How to get innerText of child div - javascript

<span class="info">
<span> Child 1 </span>
</span>
<span class="info">
<span> Child 2 </span>
</span>
$('#result').on('click', 'span', function() {
var search = $(this).children(".info").val();
I want to access the text written inside the child element of the clicked element.
It does not work with the .val function that wrote above because there is no value.
How can I do it with innertext function ?
If the top span is clicked, the value of the search variable should be Child 1, if the bottom span is clicked, its value should be Child 2.
Thank you.

Use .text().
$('#result').on('click', 'span.info', function() {
let search = $(this).find('span').text();
console.log(search);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="result">
<span class="info">
<span> Child 1 </span>
</span>
<span class="info">
<span> Child 2 </span>
</span>
</div>

Related

How to hide a list item according to its html content?

<div class="icon-list-item">
<span class="icon-list-text">One</span>
</div>
<div class="icon-list-item">
<span class="icon-list-text">Two</span>
</div>
<div class="icon-list-item">
<span class="icon-list-text">Three</span>
</div>
<div class="icon-list-item">
<span class="icon-list-text">empty</span>
</div>
I would like to hide/remove any div that contains a span with "empty" content
I have tried many functions but none of them worked. Can you help me find some JS that can solve this?
Explanation : The forEach iterates through all the div elements having class icon-list-item. The spanChild variable holds the child element of the div element of current iteration. remove() function is used to remove element from DOM, when the text inside spanChild is "empty".
var divs = document.querySelectorAll('.icon-list-item');
divs.forEach((el) => {
let spanChild = el.children[0];
if(spanChild.innerText.trim() === "empty")
el.remove();
});
<div class="icon-list-item">
<span class="icon-list-text">One</span>
</div>
<div class="icon-list-item">
<span class="icon-list-text">Two</span>
</div>
<div class="icon-list-item">
<span class="icon-list-text">Three</span>
</div>
<div class="icon-list-item">
<span class="icon-list-text">empty</span>
</div>

How to use a CSS selector that gets all matching elements except those inside a specific child?

Assume an HTML structure as shown:
<div id="container">
<div class="A">
<div id="excludedElement">
<p>
<span class="MyClass">1</span>
<span class="MyClass">2</span>
<span class="MyClass">3</span>
</p>
</div>
</div>
<div class="B">
<p>
<span class="MyClass">4</span>
<span class="MyClass">5</span>
<span class="MyClass">6</span>
</p>
</div>
</div>
I want all elements inside of the "container" div that have the class "MyClass" except for those inside of the "excludedElement" div. In this case, the result contains only the spans 4, 5, and 6.
My current solution is to first get all elements with "MyClass", then get all elements inside of excludedElement with "MyClass". For each element in the first list, we check if it's in the second, and skip over it if so. This is O(n^2) running time, so I'd like to avoid this. Psuedocode for reference:
const allElements = container.querySelectorAll('.MyClass');
const excludedElements = container.querySelectorAll('#excludedElement .MyClass');
var result = [];
for (const element in allElements)
{
if (!excludedElements.Contains(element))
{
result.Add(element);
}
}
Is there a way to craft a CSS selector in querySelectorAll() that can retrieve this particular set of elements?
One way is to temporarily remove excludedElement from the tree, query for "MyClass", then replace the excludedElement, but I want to avoid modifying the DOM.
If the structure is predictable and already known:
container.querySelectorAll('div:not(#excludedElement) > p .MyClass');
If the structure is not known and you're okay with adding classes in order to avoid O(n^2):
const excludes = [...container.querySelectorAll('#excludedElement .MyClass')];
excludes.forEach(element => element.classList.add('excluded'));
const filteredMyClass = [...container.querySelectorAll('.MyClass:not(.excluded)')];
You can select all .MyClass descendants, then .filter the collection by whether the current item being iterated over has a #excludedElement ancestor with .closest:
const classes = [...container.querySelectorAll('.MyClass')]
.filter(span => !span.closest('#excludedElement'));
for (const span of classes) {
span.style.backgroundColor = 'yellow';
}
<div id="container">
<div class="A">
<div id="excludedElement">
<p>
<span class="MyClass">1</span>
<span class="MyClass">2</span>
<span class="MyClass">3</span>
</p>
</div>
</div>
<div class="B">
<p>
<span class="MyClass">4</span>
<span class="MyClass">5</span>
<span class="MyClass">6</span>
</p>
</div>
</div>
Unless you know in advance the exact sort of structure of the descendants of #container, I don't think there's an elegant way to do this with a single query string; :not accepts simple selectors only.
Just for informational purposes, a silly and repetitive method that you shouldn't use would be to use the query string:
:scope > .MyClass,
:scope > *:not(#excludedElement) > .MyClass,
:scope > *:not(#excludedElement) > *:not(#excludedElement) > .MyClass
...
const selector = `
:scope > .MyClass,
:scope > *:not(#excludedElement) > .MyClass,
:scope > *:not(#excludedElement) > *:not(#excludedElement) > .MyClass
`;
const classes = container.querySelectorAll(selector);
for (const span of classes) {
span.style.backgroundColor = 'yellow';
}
<div id="container">
<div class="A">
<div id="excludedElement">
<p>
<span class="MyClass">1</span>
<span class="MyClass">2</span>
<span class="MyClass">3</span>
</p>
</div>
</div>
<div class="B">
<p>
<span class="MyClass">4</span>
<span class="MyClass">5</span>
<span class="MyClass">6</span>
</p>
</div>
</div>
I have this....
const Excludes = [...container.querySelectorAll('#excludedElement .MyClass')]
, noExcludes = [...container.querySelectorAll('.MyClass')].filter(el=>(!Excludes.includes(el)))
;
noExcludes.forEach(element => element.style.backgroundColor = 'lightgreen');
<div id="container">
<div class="A">
<div id="excludedElement">
<p>
<span class="MyClass">1</span>
<span class="MyClass">2</span>
<span class="MyClass">3</span>
</p>
</div>
</div>
<div class="B">
<p>
<span class="MyClass">4</span>
<span class="MyClass">5</span>
<span class="MyClass">6</span>
</p>
</div>
</div>
You can use this precise selector in .querySelectorAll():
:not(#excludedElement) > p > .MyClass
Working Example:
const includedSpans = [... document.querySelectorAll(':not(#excludedElement) > p > .MyClass')];
includedSpans.forEach((includedSpan) => console.log(includedSpan.textContent));
<div id="container">
<div class="A">
<div id="excludedElement">
<p>
<span class="MyClass">1</span>
<span class="MyClass">2</span>
<span class="MyClass">3</span>
</p>
</div>
</div>
<div class="B">
<p>
<span class="MyClass">4</span>
<span class="MyClass">5</span>
<span class="MyClass">6</span>
</p>
</div>
</div>

How should I get 'This is my name ' from multiple spans in js?

<div id='item1'>
<span>This is my name</span>
<span> This is my nickname</span>
Need JS code to fetch a specific span
You can use:
document.getElementById("item1").children[0];
To get the first child of your div (ie the first span) and then use .textContent on this node to get "This is my name"
See working example below:
const firstChild = document.getElementById("item1").children[0];
console.log(firstChild.textContent);
<div id='item1'>
<span>This is my name</span>
<span> This is my nickname</span>
</div>
Or, if you wish to use jQuery:
const firstChild = $("#item1").children().eq(0);
console.log($(firstChild).text());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='item1'>
<span>This is my name</span>
<span> This is my nickname</span>
</div>
Use selector :contains() to select the span which contains the text This is my name
$("span:contains(This is my name)").css('color', 'red')
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span>This is my name</span>
<span> This is my nickname</span>
You can use find with eq like below.
var item1 = $('#item1').find('span').eq(0).text();
var item2 = $('#item1').find('span').eq(1).text();
console.log(item1);
console.log(item2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='item1'>
<span>This is my name</span>
<span> This is my nickname</span>
</div>
Using jQuery you can use
$('#item1 > span:first-child').text()
var text = $('#item1 > span:first-child').text();
console.log(text);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='item1'>
<span>This is my name</span>
<span> This is my nickname</span>
</div>

put multi div and another multi div

I want to put a div in another div using js. I found a solution can do this but just put 1 div in div. Below html is my situation.
For example:
<body>
<div>
<span class="outer_part">
</span>
<div class="inner_part">1
</div>
</div>
<div>
<span class="outer_part">
</span>
<div class="inner_part">2
</div>
</div>
<div>
<span class="outer_part">
</span>
<div class="inner_part">3
</div>
</div>
</body>
Result:
<body>
<div>
<span class="outer_part">
<div class="inner_part">1</div>
</span>
</div>
<div>
<span class="outer_part">
<div class="inner_part">2</div>
</span>
</div>
<div>
<span class="outer_part">
<div class="inner_part">3</div>
</span>
</div>
</body>
I found solution but not work
<script>
$('.inner_part').appendTo('span.outer_part');
</script>
Your problem is that you appending all the .inner_part elements to all the .outer_part elements, but you only need to do a portion of that.
You can use each() to loop over all the .inner_parts, and attach each to its previous sibling, which is the .outer_part.
// loop over all inner parts
$('.inner_part').each(function() {
var innerPart = $(this);
var outerPart = innerPart.prev(); // inner part's previous sibling is the outer part
innerPart.appendTo(outerPart);
});
Or, shorter:
$('.inner_part').each(function() {
$(this).appendTo($(this).prev());
});
Get element by the ID, then add html inside of it to add a div in this case or anything you want.
document.getElementById('div1').innerHTML += '<div class="inner_part">1</div>';
<div id="div1"></div>

How to know which div called a function in a class?

I've got six divs that act as buttons. When clicked, one of the spans in a different div (and class) is displayed, and others are hidden.
Buttons:
<div class="menu">
<div class="menubutton">
Menu1
</div>
.
.
.
<div class="menubutton">
Menu6
</div>
</div>
Info shown based on clicked button:
<div class="information">
<span class="information1"> Info1 </span>
...
<span class="information6"> Info6 </span>
</div>
How do I know which one called the function, so I can know which span to make visible?
Provided your markup is this way:
<div class="menu">
<div class="menubutton">
Menu1
</div>
<div class="menubutton">
Menu2
</div>
<div class="menubutton">
Menu3
</div>
<div class="menubutton">
Menu4
</div>
<div class="menubutton">
Menu5
</div>
<div class="menubutton">
Menu6
</div>
</div>
<div class="information">
<span class="information1"> information1 </span>
<span class="information2"> information2 </span>
<span class="information3"> information3 </span>
<span class="information4"> information4 </span>
<span class="information5"> information5 </span>
<span class="information6"> information6 </span>
</div>
You can do this:
$('.menubutton').click(function(){
var index = $('.menubutton').index(this); //get the index of the menubutton clicked
$('.information > span').eq(index).show().siblings().hide(); // show the corresponding information item based onthe clicked one's index and hide others.
});
Demo
with this you can safely remove the class with index like information1, information2 etc instead you can add a common class say content
<div class="information">
<span class="content"> information1 </span>
<span class="content"> information2 </span>
<span class="content"> information3 </span>
<span class="content"> information4 </span>
<span class="content"> information5 </span>
<span class="content"> information6 </span>
</div>
and change it to:
$('.menubutton').click(function(){
var index = $('.menubutton').index(this); //get the index of the menubutton clicked
$('.information > .content').eq(index).show().siblings().hide(); // show the corresponding information item based onthe clicked one's index and hide others.
});
Since you can't have ID's, we can get the index of the clicked menu item, add 1, then find the corresponding information span to show:
$(".menubutton").click(function() {
var menuIndex = $(this).index() + 1;
$(".information" + menuIndex).show();
});
The this keyword inside a function refers to the element that called the function.
Add the #id for each menubutton, so:
<div class="menubutton" id="btn_1"></div>
then:
$(".menubutton").on("click", function() {
// Get the id of button clicked.
var id = $(this).attr("id").split("_")[1];
// Target SPAN with the same id.
$("SPAN.information" + id).show();
});

Categories