Get text from p, not including span values, using Document.querySelector - javascript

I have this element structure.
<p>
<span class="ts-aria-only">
Departure
</span>
RUH
<span class="ts-aria-only"> Riyadh</span>
</p>
I'm trying to get the text RUH, but using innerText will return the whole text including the value inside <span>.
Some answers posted here on SO uses ajax, which is not applicable for my use case.

It's a text node, so it can't be selected with a query string. You'll have to start from its parent element and access the appropriate childNodes index:
console.log(
document.querySelector('p').childNodes[2].textContent.trim()
);
<p>
<span class="ts-aria-only">
Departure
</span>
RUH
<span class="ts-aria-only"> Riyadh</span>
</p>

this should work
Array.from(document.querySelector('p').childNodes).reduce((a,b) => a += b.nodeType==3 ? b.textContent.trim() : '' ,'')
basically you need to check each childNode if it is textNode (nodeType==3)
then you could do with it whatever you want

Related

getElementById not working in class method

HTML:
<div id='verse'>
<p id='text'>
<span id = 'reference'>random stuff here</span>
random stuff here
</p>
</div>
JS:
class Verse {
...
update() {
document.getElementById('text').innerHTML = 'text';
document.getElementById('reference').innerHTML = 'reference';
}
...
}
Whenever I call .update in an instance of Verse, the paragraph element's text changes without a problem but trying to change the span's text gives me an error: TypeError: Cannot set properties of null. Does not work with innerText either. It works fine if I change it outside of the class. Thanks for the help!
Setting innerHTML on #text replaces the contents of the <p> entirely, so when you subsequently try to access #reference it no longer exists.
The simplest way to avoid this would be to add another span and replace its text instead of the entire <p>.
<div id='verse'>
<p>
<span id='reference'>random stuff here</span>
<span id='text'>random stuff here</span>
</p>
</div>

add an empty line between 2 spans

I am trying to add an empty line between two text spans
<span> The models have random values that I dont understand and it is not sufficenit but whatever </span>
{'\n'}
<span>Lots of text here </span>
The {'\n'} does not seem to work. What else can I try?
use <br/> tag for this purpose
<span> The models have random values that I dont understand and it is not
sufficenit but whatever </span>
<br />
<span>Lots of text here </span>
As ali said you can use <br>
Or instead you can put them into <p> tag because they are text ... span is not usually used on Lots of text
Code should be like this
<p> The models have random values that I dont understand and it is not sufficenit but whatever </p>
<p>Lots of text here </p>

count child element and text with it jquery

I want to count the total element and text inside the p tag
<p class="parent">
<span class="child">Span Text</span>
Text Text Text
</p>
it is possible?
$(p).children(').length
I'm using this code and this giving me 1 only but I want count 2.
You are looking for child nodes, and not children (read more about the difference here).
However, note that the actual number of child nodes in your HTML code would be 3, since there's a text node that holds the spaces before the span.
In this example, you can see the count of child nodes with or without the space before the span.
const parent1ChildNodes = document.querySelector('.parent1').childNodes.length
const parent2ChildNodes = document.querySelector('.parent2').childNodes.length
console.log(parent1ChildNodes)
console.log(parent2ChildNodes)
<p class="parent1">
<span class="child">Span Text</span>
Text Text Text
</p>
<p class="parent2"><span class="child">Span Text</span>
Text Text Text
</p>
children method only returns valid objects. "Text Text Text" is not an html object. Therefore it doesn't count. If you place it in another span, the length of the children becomes 2.
<p class="parent">
<span class="child">Span Text</span>
<span>Text Text Text</span>
</p>
You need to use contents instead of children to get text nodes counted. Note that contents will also count comment nodes.
$(p).contents().length

How to select the last child inside the tree using jQuery?

Suppose I have such a structure:
<div id="content">
<div>
<span>
<b>
<i>
<u>
<span>Price</span>
</u>
</i>
</b>
</span>
</div>
</div>
In this case, the number of tags inside the div #content and which ones they don't know me. I only have access to the id content.
How do I get the selector to the latest span which contains the text Price?
p.s. lastChild method returns the last child within the selected selector, but not deeper!
Select all children of #content using * selector and use .filter() to filtering element. In callback filter elements hasn't any child.
$("#content *").filter(function(){
return $("*", this).length == 0;
});
// Or using ES6
$("#content *").filter((i,v) => $("*", v).length == 0);
var ele = $("#content *").filter((i,v) => $("*", v).length == 0);
console.log(ele[0].outerHTML);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content">
<div>
<span>
<b>
<i>
<u>
<span>Price</span>
</u>
</i>
</b>
</span>
</div>
</div>
You can use .find():
https://api.jquery.com/find/
This will recursively look for your selector, so:
$('#content').find('span') will give you two spans, one for the first nested span and one for the second nested span. The downside is that if you have multiple spans you'll need to find the right one.
If you can put an identifier in the last one, say a class named 'target-class', than you know you'll find the right one:
$('#content').find('span.target-class');
First of all let's fix your syntax. You can't put an <span> directly within a <u>. You need a <li> node. Also you can't/shouldn't put block elements such as ul within inline elements (span, a, b, i...). And even <b> and <i> are not recommended, better use semantic markup such as <strong> or <em> instead.
Now your problem. I think you don't have to care about being the last node. If you know the text contained is "Price" you can look for it in the following way:
var selector = $('#content').find(":contains('Price')");
$(selector).addClass('highlighted');
.highlighted {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content">
<div>
<u>
<li>
<span>Price</span>
</li>
</u>
</div>
</div>
If this solution does not fits your needs, to get the last node you have to get all of them an check if they have children or not. Once they don't, you've reached your target.
But I have to say that this is a solution you could have found in SO.
Select deepest child in jQuery
Jquery Way -
You could target all spans $() and target the latest span using slice() method.
$('#content span').slice(-1)[0];
Javascript way -
Find all spans using querySelectorAll(), You'd get a NodeArray, you can convert it to Array using Array.from() and slice() last item from it which is latest span.
Array.from(document.querySelectorAll('#content span')).slice(-1)[0]

Change only text (Jquery)

I have a small problem that i cannot solve.I have this : <p>Text<span></span></p> and i want to change only the text of the <p>.Which means, when i click on an change-Button, the text based on an input field should replace the text.
What i have tried is something like this : $("p").text("newText") but this will also remove the <span>.
So how can i only change the text and not the inner html...
With your HTML above you can do
$('p').contents().first()[0].textContent='newText';
The idea is to take advantage of the fact that contents() includes text-nodes. Then, access by index [0] to get the native javascript DOM element and set the textContent
$('p').contents().first()[0].textContent = 'newText';
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<p>Text<span>inside span</span>
</p>
Put another span inside of the p tag and only change its contents:
<p>
<span id="theText">Text</span>
<span></span>
</p>
And then:
$('#theText').text('newText');
$('#theText').text('newText')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>
<span id="theText"></span>
<span>some other span</span>
</p>

Categories

Resources