How do I replace part of text inside an element with children? - javascript

I have this HTML:
<div class="test">Orange <span class="is">is</span> my favorite color.</div>
I only want to replace Orange (and the space after it). Using .text() won't work because it selects the whole strong.
How do I do this?

This is harder to do with jQuery than with the native DOM, so if you're using jQuery, you're going to have to convert the element to the native DOM using jQuery's array indexing.
Basically, what we need to do is change the first text node. jQuery isn't really good with text nodes, which is why we use the DOM here:
//This gets the div.test element using jQuery:
var testDiv = $("div.test");
function changeColor(color) {
/* The following function changes the value of the first text node within testDiv: */
//This converts testDiv from a jQuery element to a regular DOM element. This is because jQuery isn't really meant to be handling stuff like text nodes, so doing this with the regular DOM will just be much easier.
var domElement = testDiv[0];
//Now, just change the value of the first text node:
domElement.childNodes[0].nodeValue = color;
}
//Now, as you can see if you click div.test, we can replace the color mentioned in div.test using changeColor():
testDiv.click(function() {
changeColor("Blue ");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">Orange <span class="is">is</span> my favorite color.</div>

You should use native DOM methods. In your case the simples thing is just change nodeValue property of the first childNode element (which you know is going to be TextNode element):
var el = $('.test');
el[0].childNodes[0].nodeValue = 'Green ';
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">Orange <span class="is">is</span> my favorite color.</div>
or if you want you can grab text node with jQuery's $.fn.contents method:
var el = $('.test');
el.contents()[0].nodeValue = 'Green ';
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test">Orange <span class="is">is</span> my favorite color.</div>

If you are using jquery, here is the solution
$('.test').html(function(){
return $(this).html().replace('Orange ','');
});
Find the fiddle here: https://jsfiddle.net/MasoomS/xff6dw1t/
Used data attribute to refine the code and to use it for multiple strings
HTML:
<div class="test" data-replace="Orange ">Orange <span class="is">is</span> my favorite color.</div>
<div class="test" data-replace="Green ">Green <span class="is">is</span> my next favorite color.</div>
JQUERY:
$('.test').html(function(){
return $(this).html().replace($(this).data('replace'),'');
});

document.getElementsByClassName("test")[0].childNodes[0].nodeValue = "Black";

Related

Using Filter to return content within class and the class itself

Filter behaves as expected, it returns multiple divs with a class of post. However, it only returns the content within the div
<h1></h1>
and not
<div class="post"><h1></h1></div>
Would it be possible to get this sort of output?
I.e. this sort of output
<div class="post"><h1></h1></div>
Here's the code:
$(result).filter('.post').each(function(i, currentElement) {
var htmlOfSinglePost = $(this).html();
var p = $(htmlOfSinglePost).attr("data-post-id");
console.log(p);
});
$(this).html(); would give you the inner HTML of the specified selector excluding the selector itself.
It you want inner html and selector element itself, you may want to use
$(selector)[0].outerHTML
here is snippet
$(".post").each(function(){
console.log($(this)[0].outerHTML)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="post"><h1></h1></div>
<div class="post"><h1>This is other one</h1></div>
Assuming your result contains HTML, given some basic example HTML, within your .each() the this refers to the current HTML element (not the jQuery) object. To get the outer HTML element, you can use outerHTML as seen below.
To get the data-post-id value from the outer content, wrap it into a jQuery wrapper to use $(outerContent).data('postId').
Just to add, the reason you cannot use getAttribute() on a result
from outerHTML is because outerHTML resturns a
DOMString
and while you can take the DOMString and convert it into an element it
is faster at this point to just use jQuery $(...outerHTML).data() but only because you are already using it
$('.post').each(function(i, currentElement) {
var outerContent = this.outerHTML;
console.log(outerContent);
var p = $(outerContent).data('postId');
console.log('postId = ',p);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="post" data-post-id="15">
<h1>Post</h1>
</div>
<div class="post" data-post-id="57">
<h1>Post 2</h1>
</div>

How to copy and alert an child element

$('h1').click(function(){
var span = $(this).find('.secondary');
alert(span);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>
Hello
<span class='secondary'>World</span>
</h1>
How to i copy the entire .secondary element and alert it like this
<span class='secondary'>World</span>
There's a few problems with your solution:
alert the span's outerHTML instead of just the JQuery span object.
.secondary instead of secondary for your selector (the . indicates that it's a class, read more here).
Use $(document).ready() This will make sure that JQuery is loaded and ready to be used, and that all the elements are loaded before running any JQuery.
In the end, with all these problems solved, your code should look like this:
$(document).ready(function () {
$('h1').click(function () {
var span = $(this).find('.secondary');
alert(span[0].outerHTML);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>
Hello
<span class='secondary'>World</span>
</h1>
What you want is the outer HTML of the currently selected element. There is no direct function for this in jQuery, so you need to:
first wrap it in another element,
then go upward to that wrapper element
now you can use html() to get inner html of this wrapper element, which is actually the outer html for your original element.
You can use jQuery's clone() method to create a copy and perform the manipulations on that clone element, thus keeping your original element as it is.
$('h1').click(function(){
var span = $(this).find('.secondary').clone().wrap('<p>').parent().html();
alert(span);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>
Hello
<span class='secondary'>World</span>
</h1>
To then grab the html element as a string you would do:
document.documentElement.outerHTML
<script>
$('h1').click(function () {
var span = document.find('secondary').outerHTML;
alert(span);
})
</script>

JavaScript equivalent to JQuery .next()

Is there a JavaScript method similar to jQuery .next()? I want to find the next element that has the class of "error" relative to the element. I've tried using .nextSibling as a loop but couldn't figure it out. Didn't know if there was an easier way to go about it without jQuery.
For instance, if I have this code:
<div id="section">
<div id="test">test</div>
<span class="info">Information</span>
<span class="error">Error!</span>
</div>
I'm trying to get the next .error class closest to #test, if I have a #section2 and a #test2 I would want to get the .error class closest to #test2 and so on.
The nextElementSibling property returns the element immediately following the specified element, in the same tree level.
Example: Get the HTML content of the next sibling of a list item:
var x = document.getElementById("item1").nextElementSibling
The nextElementSibling property might help.
Best bet would be to search through the jQuery code and see what they did.
http://code.jquery.com/jquery-2.0.3.js
At a glance, I do see some calls to "nextSibling" and "previousSibling."
Also see here:
How to get next element using JavaScript-only?
Hope this helps!
This is the pure javascript for you:
HTML
<div id="nodes">
<div class="error">This is error Node</div>
<div class="nextElement">This is next Element</div>
</div>
Javscript:
var nodes = Array.prototype.slice.call( document.getElementById('nodes').children ),
errorNode = document.getElementsByClassName('error')[0];
var indexOfError = nodes.indexOf(errorNode);
var nextElement = nodes[indexOfError + 1];
alert(nextElement.innerText);
Here is demo
Sounds like you may be looking for document.getElementsByClassName()... if the elements with class=error are not direct siblings in the DOM, then there's not a good way to find them otherwise. It's elementary, but you can just search through the array returned by document.getElementsByClassName('error') until you find your starting element, and then you know the next item in the array will be the next element in the DOM.
See also MDN reference. Won't work in old IE, but works for all modern browsers.

How to merge paragraphs into parent link with jquery / Javascript?

How do I turn this:
<a class="link">
<p class="paragraph">This is some text</p>
<p class="paragraph">This is some more text</p>
<p class="paragraph">And some more</p>
</a>
into this:
<a class="link">
This is some text This is some more text And some more
</a>
with jQuery. I tried using append and merge but I just can't figure it out.
Since the text method returns the text content of an element and it's descendants, you can just use that:
var link = $("a.link");
link.text(link.text());​​​​​​​​​
From the docs:
Get the combined text contents of each element in the set of matched
elements, including their descendants.
Here's a working example.
Update (see comments)
In the case that this needs to apply to multiple .link elements, you can use each:
$("a.link").each(function() {
$(this).text($(this).text());
});
This will work:
$("a.link").text(function(i,text){
return text;
});
And yet another way (not tested):
// you can optionally filter to
// only p elements too with
// .children("p")
$("a.link").children().contents().unwrap();
Here's another variation of the second:
$("a.link p").contents().unwrap();
Edit: Just a note for clarity:
All of these solutions work on multiple elements. The first solution is a relatively uncommon syntax that can be used on most jQuery setter functions. It runs the callback on each matched element and sets the value of the property/attribute to the value returned from the callback.
try this
$(document).ready(function(){
var concatText = "";
$("p.paragraph").each(function(){
concatText = concatText + " " + $(this).text()
});
$("a.link").html(concatText);
​ });​

Add text before or after an HTML element

If i have an HTML element like <div> with some text inside or another elements can I add before or after this div some text data without an html element, just plain text?
I'd like to use only pure Javascript.
Something like :
<div id="parentDiv">
my text must be added here
<div id="childDiv"></div>
</div>
Yes, you can create a text node with document.createTextNode('the text')
Then you can insert it like an element, with appendChild or insertBefore.
Example that insert a text before #childDiv:
var text = document.createTextNode('the text');
var child = document.getElementById('childDiv');
child.parentNode.insertBefore(text, child);
Just for the record:
div.insertAdjacentHTML( 'beforeBegin', yourText );
where div is your child-DIV.
Live demo: http://jsfiddle.net/ZkzDk/
If you just need text, I find that element.insertAdjacentText(position, text) is flexible for many scenarios and is also compatible with older browsers like IE6. Where position is exactly where you want the text to be and text is the text node or just a string. The options are:
'beforebegin' Before the element itself.
'afterbegin' Just inside the element, before its first child.
'beforeend' Just inside the element, after its last child.
'afterend' After the element itself.
Like this:
let div = document.getElementById('parentDiv');
div.insertAdjacentText('afterbegin', 'My Plain Text..');
In regards to the topic and the users question for inserting before or after, here is an example for after:
var text = document.createTextNode("my text must be added here.");
var childTag = document.getElementById("childDiv");
childTag.parentNode.insertBefore(text, childTag.nextSibling);
If the childTag does not have any siblings, it is okay because the insertBefore method handles this case and simply adds it as the last child.
Also can possibly use the appendChild() method after creating text node then add your childTag via the parentNode.
You can add text node. Create node - document.createTextNode('text') and then insert/append/replace - do whatever you want.
Something like this should do it:
<script type="text/javascript">
var parent = document.getElementById('parentDiv');
var sibling = document.getElementById('childDiv');
var text = document.createTextNode('new text');
parent.insertBefore(text, sibling);
</script>

Categories