My problem is to split the Dom element using jquery.
<span class="start">
<span class="second">
new text <span class='split'>is written</span> in this place.
</span>
</span>
And I want to Split the above DOM Like this.
<span class="start"><span class="second">new text</span></span>
<span class="start"><span class="second">is written</span></span>
<span class="start"><span class="second">in this place.</span></span>
Please, anybody give me some advice.
One way to do it would be:
last_text=$('.split')[0].nextSibling; //get textNode after split span
prev_text=$('.split')[0].previousSibling; //get text Node before split span
current=$('.split').text(); //get split span text
$('.second').html(' '); //clear current html
cloned1=$('.start').clone(); // clone el
cloned1.insertAfter($('.start'));
cloned2=$('.start').first().clone(); //clone one more
cloned2.insertAfter($('.start').last());
//set text for elements
$('.start .second').eq(0).html(prev_text);
$('.start .second').eq(1).html(current);
$('.start .second').eq(2).html(last_text);
Demo:
last_text=$('.split')[0].nextSibling; //get textNode after split span
prev_text=$('.split')[0].previousSibling; //get text Node before split span
current=$('.split').text(); //get split span text
$('.second').html(' '); //clear current html
cloned1=$('.start').clone(); // clone el
cloned1.insertAfter($('.start'));
cloned2=$('.start').first().clone(); //clone one more
cloned2.insertAfter($('.start').last());
//set text for elements
$('.start .second').eq(0).html(prev_text);
$('.start .second').eq(1).html(current);
$('.start .second').eq(2).html(last_text);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="start">
<span class="second">
new text <span class='split'>is written</span> in this place.
</span>
</span>
P.S. If there are no classes (i guess that could be the case), you will have to use different selectors, to target spans (inside container?), with eq(), maybe, but, basically, this simple logic should work...
Related
So basically it makes "a +b=c". But I want to make "a+b=c".
HTML:
<div class="container">
<span id="b__value">+b</span>
<span id="c__value">=c</span>
</div>
JS:
const vlaueContainer = document.getElementsByClassName('timer__value')[0];
let newSpan = document.createElement('span');
newSpan.id = 'testId';
newSpan.innerHTML += "77";
valueContainer.insertBefore(newSpan, valueContainer.firstChild);
Generally, Inline Elements in HTML when used in different lines, (just as you did), are rendered on the page with a blank space between the elements.
If you want the output as expected, put the two elements in a single line, and not in different lines.
<div class="container">
<span id="b__value">+b</span><span id="c__value">=c</span>
</div>
I have a div with some children within and its directly contained text like below:
<div id="price">
100$
<span>some ads</span>
<span>another ads</span>
for each
</div>
I want to get directly contained text '100$' in this DOM element.
I tried with innerHTML, innerText and textContent.
But they show all text including children's text like below:
const element = document.getElementById('price');
console.log(element.innerText);
console.log(element.innerHTML);
console.log(element.textContent);
<div id="price">
100$
<span>some ads</span>
<span>another ads</span>
for each
</div>
The expected result is 100$(I don't need "for each") which is directly contained text in parent element. So then I can get the price and its currency.
note: jquery is also allowed to use.
.clone() clones the selected element.
.children() selects the children from the cloned element
.remove() removes the previously selected children
.end() selects the selected element again
.text() gets the text from the element without children
const elementText = $("#price").clone()
.children()
.remove()
.end()
.text();
console.log(elementText.trim().split("\n")[0]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="parent">
Parent
<span>Child 1</span>
<span>Child 2</span>
</div>
<div id="price">
100$
<span>some ads</span>
<span>another ads</span>
for each
</div>
EDIT: You can also use this:
$("#price").contents().get(0).nodeValue.trim()
Filter the childNodes to include only text nodes and use textContent of each of the matching nodes:
const text = Array.prototype.filter
.call(element.childNodes, (child) => child.nodeType === Node.TEXT_NODE)
.map((child) => child.textContent)
.join('');
The text includes the full markup of the text, including newlines. If this is undesired, use text.trim().
The filter.call is used because childNodes is a NodeList, which is array-like, but does not support .filter method.
To get text only for the first node
const text = Array.prototype.filter
.call(element.childNodes, (child) => child.nodeType === Node.TEXT_NODE)[0];
Alternatively, if you can rely on the fact that the value is always the first child, the above can be simplified to
const text = element.childNodes[0];
With jQuery :
const text = $($('#price').contents()[0]).text().trim();
You can do this using the "outerText" property. Like in the example below:
var text = document.querySelector('body').outerText;
var regex = /([\d]+)\$/g;
console.log(text.match(regex).join());
<div id="price">
100$
<span>some ads</span>
<span>another ads</span>
for each
</div>
<div class="myDiv">
<span class="mySpan">SAMPLE TEXT A</span>
<span class="mySpan">SAMPLE TEXT B</span>
</div>
I'm struggling to get the right javascript to hide "myDiv" if the text in "mySpan" is "SAMPLE TEXT A".
Somehow like this (you will not see anything, because <div class="myDiv"> is hidden already):
var spans = document.getElementsByClassName('mySpan')
for(var i = 0; i < spans.length; i++) {
if(spans[i].innerHTML === 'SAMPLE TEXT A') spans[i].parentElement.style.display = 'none';
}
<div class="myDiv">
<span class="mySpan">SAMPLE TEXT A</span>
<span class="mySpan">SAMPLE TEXT B</span>
</div>
UPDATE
"What is the significance of the 'for' statement?"
document.getElementsByClassName('mySpan') will select ALL elements with class mySpan, think about it as an array. Then i iterate through all selected span's and finding the case, where innerHTML is equal to our specific string.
"In the if statement, how would I specify just the parent div and not every element with class "myDiv"? There are other elements on the page with that class."
If so, you need to use parentElement (I have updated my answer with needed row).
I need to change a text in a span.
<span class="count_bottom">
<i class="blue">
<i class="fa fa-sort-asc"></i>
12%
</i>
From last seen
</span>
I only need to change From last seen text according to button click event.
How can I do this?
Filter out non-empty text nodes inside space and then replace with new content.
$('.count_bottom')
// get all child nodes
.contents()
// filter out non-empty text node
.filter(function() {
// check node type and content
return this.nodeType === 3 && this.nodeValue.trim().length;
// replace it with new content
}).replaceWith('new text');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="count_bottom"><i class="blue"><i class="fa fa-sort-asc"></i>12% </i> From last seen</span>
With pure JavaScript
// get the `i` tag inside `span`
document.querySelector('.count_bottom > i')
// get adjacent text node which is immediately after the element
.nextSibling
// update text content of the text node
.textContent = 'new text';
<span class="count_bottom"><i class="blue"><i class="fa fa-sort-asc"></i>12% </i> From last seen</span>
You can select first i element in span and use nextSibling property to getting next sibling text of it.
$("button").click(function(){
$(".count_bottom > i")[0].nextSibling.nodeValue = "New value";
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>Change text</button>
<span class="count_bottom">
<i class="blue">
<i class="fa fa-sort-asc"></i>
12%
</i>
From last seen
</span>
I have some html that is in the form
<span class="prefix">something</span> (Optional)
Text
<span class="badge">Something else</span> (optional, can be multiple)
<span class="postfix">Another thing</span>
And I want to wrap the Text, but not the spans, in another span so that I can extract and replace it using jQuery as necessary. I can't edit the back end code that is generating this HTML. Given that I don't know in advance whether the first span will be there, or how many spans there will be at the end, is there any way to wrap the plain text so that it can be operated on?
I am hoping to get an output that looks something like this:
<span class="prefix">something</span>
<span class="txt">Text</span>
<span class="badge">something else</span>...
<span class="postfix">another thing</span>
Try this:
$('#container').contents()
.filter(function() { return this.nodeType === 3 })
.wrap('<span class="txt" />');
Based on this answer: https://stackoverflow.com/a/5291776/616535
filter() the contents() of the container element to those that are pure text nodes
wrap() them in a span
$('#container').contents().filter(function() {
return $(this)[0].nodeValue && $(this)[0].nodeValue.trim();
}).wrap('<span class="txt"/>');
.txt{
color:green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="container">
<span class="prefix">something</span>
Text
<span class="badge">Something else</span>
<span class="postfix">Another thing</span>
</div>