I'm trying to remove the text node "one".
$targetDiv is jQuery object
$targetDiv[0].outerHTML
<div><div>one<font face="Impact" size="4">www</font></div></div>
$targetDiv[0].innerHTML
<div>one<font face="Impact" size="4">www</font></div>
I can remove the other text node "www" like below:
$targetDiv.find("font").each(function ()
{
if (this.firstChild.nodeType === 3)
{
this.firstChild.data = "";
}
});
But having tough time removing the "one" part.
$targetDiv[0].firstChild
<div>
$targetDiv[0].firstChild.data
undefined
$targetDiv[0].firstChild.innerText
undefined
$targetDiv[0].firstChild.innerHTML
"one<font face="Impact" size="4">www</font>"
$targetDiv[0].firstChild.innerText
undefined
$targetDiv[0].firstChild.textContent
"onewww"
It's not very clear what context this is in, or what $targetDiv is, but based on the results you're getting we can assume you are using Firefox, and that $targetDiv is the first div, and that this should work
$($targetDiv.find("div").get(0).firstChild).remove();
FIDDLE
You can use the native .removeChild method to remove the first text node:
var div=targetDiv[0].firstChild;
div.removeChild(div.firstChild);
This method is invoked from the parent of the node that you wish to remove, and receives the node to remove as its argument.
Modern browsers let you simply call .remove() on the node itself.
target[0].firstChild.firstChild.remove();
Your .each() loop was close. In that particular case, since the one text node is the only sibling that is a text node, you'd just iterate the children under target since there's only one.
$targetDiv.children("div").each(function ()
{
if (this.firstChild.nodeType === 3)
{
this.firstChild.data = "";
}
});
Though targeting it directly instead of a loop makes more sense in this case.
Try,
$($targetDiv.children('div').contents()[0]).remove();
DEMO
Related
I have an element E and I'm appending some elements to it. All of a sudden, I find out that the next element to append should be the first child of E. What's the trick, how to do it? Method unshift doesn't work because E is an object, not array.
Long way would be to iterate through E's children and to move'em key++, but I'm sure that there is a prettier way.
var eElement; // some E DOM instance
var newFirstElement; //element which should be first in E
eElement.insertBefore(newFirstElement, eElement.firstChild);
2018 version - prepend
parent.prepend(newChild) // [newChild, child1, child2]
This is modern JS! It is more readable than previous options. It is currently available in Chrome, FF, and Opera.
The equivalent for adding to the end is append, replacing the old appendChild
parent.append(newChild) // [child1, child2, newChild]
Advanced usage
You can pass multiple values (or use spread operator ...).
Any string value will be added as a text element.
Examples:
parent.prepend(newChild, "foo") // [newChild, "foo", child1, child2]
const list = ["bar", newChild]
parent.append(...list, "fizz") // [child1, child2, "bar", newChild, "fizz"]
Related DOM methods
Read More - child.before and child.after
Read More - child.replaceWith
Mozilla Documentation
Can I Use
2017 version
You can use
targetElement.insertAdjacentElement('afterbegin', newFirstElement)
From MDN :
The insertAdjacentElement() method inserts a given element node at a given position relative to the element it is invoked upon.
position
A DOMString representing the position relative to the element; must be one of the following strings:
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.
element
The element to be inserted into the tree.
In the family of insertAdjacent there is the sibling methods:
element.insertAdjacentHTML('afterbegin','htmlText')`
That can inject html string directly, like innerHTML but without override everything, so you can use it as a mini-template Engin and jump the oppressive process of document.createElement and even build a whole component with string manipulation process
element.insertAdjacentText for inject sanitize string into element . no more encode/decode
You can implement it directly i all your window html elements.
Like this :
HTMLElement.prototype.appendFirst = function(childNode) {
if (this.firstChild) {
this.insertBefore(childNode, this.firstChild);
}
else {
this.appendChild(childNode);
}
};
Accepted answer refactored into a function:
function prependChild(parentEle, newFirstChildEle) {
parentEle.insertBefore(newFirstChildEle, parentEle.firstChild)
}
Unless I have misunderstood:
$("e").prepend("<yourelem>Text</yourelem>");
Or
$("<yourelem>Text</yourelem>").prependTo("e");
Although it sounds like from your description that there is some condition attached, so
if (SomeCondition){
$("e").prepend("<yourelem>Text</yourelem>");
}
else{
$("e").append("<yourelem>Text</yourelem>");
}
I think you're looking for the .prepend function in jQuery. Example code:
$("#E").prepend("<p>Code goes here, yo!</p>");
I created this prototype to prepend elements to parent element.
Node.prototype.prependChild = function (child: Node) {
this.insertBefore(child, this.firstChild);
return this;
};
var newItem = document.createElement("LI"); // Create a <li> node
var textnode = document.createTextNode("Water"); // Create a text node
newItem.appendChild(textnode); // Append the text to <li>
var list = document.getElementById("myList"); // Get the <ul> element to insert a new node
list.insertBefore(newItem, list.childNodes[0]); // Insert <li> before the first child of <ul>
https://www.w3schools.com/jsref/met_node_insertbefore.asp
I have an html element that I'm replacing with a clone of itself to remove event listeners. However, I still want to interact with it after I've replaced it. Unfortunately,
node.replaceWith(node.cloneNode(true))
makes node link to an element that doesn't exist. Is there any way I can get the element that is now where it was? I know I can circumvent this by giving it an id before and querying for it after, but it feels like there should be a better way.
You'll need to store the clone before replacing and then reassign node.
To avoid having the clone hanging around you can wrap the method in a function that returns the clone.
function replaceSelf(node) {
const clone = node.cloneNode(true);
node.replaceWith(clone);
return clone;
}
let node = document.getElementById('to-clone');
node = replaceSelf(node);
node.style.backgroundColor = 'cyan';
<div>
<p id="to-clone">paragraph</p>
</div>
Try replacing this:
node = node.replaceWith(node.cloneNode(true))
with this
node.replaceWith(node.cloneNode(true))
Because replaceWith returns undefined
I have a DOM node, lets say node and this may have some children and has text in it. I need to get only the text from it.
I know that node.innerHTML gives the whole data between the tags but I don't need the child elements. This can be done using jquery once i get the node's id How to get text only from the DIV when it has child elements with text using jQuery? But in that case I am again finding the node which is a waste of time. Right now I already have the node and I only need to get its text. I tried node.text but it is returning undefined value.
Please help.
Looping over the .childNodes and grabbing the .nodeValue of the text nodes should work:
var foo = document.getElementById('foo'),
txt = '';
[].forEach.call(foo.childNodes, function (subNode) {
if (subNode.nodeType === 3) {
txt += subNode.nodeValue;
}
});
console.log(txt);
jsBin
.childNodes is a NodeList, not an array. You cannot use array methods on them, foo.childNodes.forEach() would not work.
NodeList objects are however array-like objects, so we can use Function.prototype.call to treat foo.childNodes as if it were a real array and call Array.prototype.forEach on it.
The callback we provide .forEach checks the .nodeType of each Node, if it is a text node (a Node with a .nodeType of 3) we append it's value to our output buffer.
I am not sure if I understand correctly but if you need the text for each element of the node then for JQuery you would do:
node.each(function (index){
console.debug($(this).text());
});
I'm writing a Chrome content script extension and I need to be able to target a specific element that, unfortunately, has no unique identifiers except its parent element.
I need to target the immediate first child element of parentElement. console.log(parentElement) reports both of the child elements/nodes perfectly, but the succeeding console logs (the ones that target the childNodes) always return an undefined value no matter what I do.
This is my code so far
(I have excluded the actual names to avoid confusion and extra, unnecessary explanation)
function injectCode() {
var parentElement = document.getElementsByClassName("uniqueClassName");
if (parentElement && parentElement.innerHTML != "") {
console.log(parentElement);
console.log(parentElement.firstElementChild);
console.log(parentElement.firstChild);
console.log(parentElement.childNodes);
console.log(parentElement.childNodes[0]);
console.log(parentElement.childNodes[1]);
} else {
setTimeout(injectCode, 250);
}
}
How do I select the first child element/node of parentElement?
Update:
parentElement.children[0] also has the same error as parentElement.childNodes[0].
Both these will give you the first child node:
console.log(parentElement.firstChild); // or
console.log(parentElement.childNodes[0]);
If you need the first child that is an element node then use:
console.log(parentElement.children[0]);
Edit
Ah, I see your problem now; parentElement is an array.
If you know that getElementsByClassName will only return one result, which it seems you do, you should use [0] to dearray (yes, I made that word up) the element:
var parentElement = document.getElementsByClassName("uniqueClassName")[0];
I have an element E and I'm appending some elements to it. All of a sudden, I find out that the next element to append should be the first child of E. What's the trick, how to do it? Method unshift doesn't work because E is an object, not array.
Long way would be to iterate through E's children and to move'em key++, but I'm sure that there is a prettier way.
var eElement; // some E DOM instance
var newFirstElement; //element which should be first in E
eElement.insertBefore(newFirstElement, eElement.firstChild);
2018 version - prepend
parent.prepend(newChild) // [newChild, child1, child2]
This is modern JS! It is more readable than previous options. It is currently available in Chrome, FF, and Opera.
The equivalent for adding to the end is append, replacing the old appendChild
parent.append(newChild) // [child1, child2, newChild]
Advanced usage
You can pass multiple values (or use spread operator ...).
Any string value will be added as a text element.
Examples:
parent.prepend(newChild, "foo") // [newChild, "foo", child1, child2]
const list = ["bar", newChild]
parent.append(...list, "fizz") // [child1, child2, "bar", newChild, "fizz"]
Related DOM methods
Read More - child.before and child.after
Read More - child.replaceWith
Mozilla Documentation
Can I Use
2017 version
You can use
targetElement.insertAdjacentElement('afterbegin', newFirstElement)
From MDN :
The insertAdjacentElement() method inserts a given element node at a given position relative to the element it is invoked upon.
position
A DOMString representing the position relative to the element; must be one of the following strings:
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.
element
The element to be inserted into the tree.
In the family of insertAdjacent there is the sibling methods:
element.insertAdjacentHTML('afterbegin','htmlText')`
That can inject html string directly, like innerHTML but without override everything, so you can use it as a mini-template Engin and jump the oppressive process of document.createElement and even build a whole component with string manipulation process
element.insertAdjacentText for inject sanitize string into element . no more encode/decode
You can implement it directly i all your window html elements.
Like this :
HTMLElement.prototype.appendFirst = function(childNode) {
if (this.firstChild) {
this.insertBefore(childNode, this.firstChild);
}
else {
this.appendChild(childNode);
}
};
Accepted answer refactored into a function:
function prependChild(parentEle, newFirstChildEle) {
parentEle.insertBefore(newFirstChildEle, parentEle.firstChild)
}
Unless I have misunderstood:
$("e").prepend("<yourelem>Text</yourelem>");
Or
$("<yourelem>Text</yourelem>").prependTo("e");
Although it sounds like from your description that there is some condition attached, so
if (SomeCondition){
$("e").prepend("<yourelem>Text</yourelem>");
}
else{
$("e").append("<yourelem>Text</yourelem>");
}
I think you're looking for the .prepend function in jQuery. Example code:
$("#E").prepend("<p>Code goes here, yo!</p>");
I created this prototype to prepend elements to parent element.
Node.prototype.prependChild = function (child: Node) {
this.insertBefore(child, this.firstChild);
return this;
};
var newItem = document.createElement("LI"); // Create a <li> node
var textnode = document.createTextNode("Water"); // Create a text node
newItem.appendChild(textnode); // Append the text to <li>
var list = document.getElementById("myList"); // Get the <ul> element to insert a new node
list.insertBefore(newItem, list.childNodes[0]); // Insert <li> before the first child of <ul>
https://www.w3schools.com/jsref/met_node_insertbefore.asp