I'm trying to insert the whole element into the container element however It throws some object into the DOM
JS:
const CONTAINER = document.getElementById('container');
let title = document.querySelector('h1').cloneNode(true);
CONTAINER.insertAdjacentHTML('beforeend', title);
HTML:
<div class="container" id="container"></div>
<h1>Test</h1>
Or, as a one-liner:
document.getElementById('container').insertAdjacentHTML('beforeend', document.querySelector('h1').outerHTML);
<div class="container" id="container">This is the target container</div>
<p>Some padding text</p>
<h1>Test</h1>
title it is an HTMLElementObject. Use appendChild instead.
const CONTAINER = document.getElementById('container');
let title = document.querySelector('h1').cloneNode(true);
CONTAINER.appendChild(title);
<div class="container" id="container"></div>
<h1>Test</h1>
Related
If the element has children insert a new div "i-new-element". parent2 and parent3 get a new div.
child3-parent3 has children but doesn't get a new giant. Why?
How can I make it possible for children who have children to get a new div?
it should look like:
<div id="child3-parent3">
<div id="i-new-element"></div>
<div id="child3"></div>
<div id="child4"></div>
</div>
var container = document.getElementById("container").querySelectorAll("#container > *");
container.forEach(function(div) {
{
if (div.hasChildNodes()) {
let parentElement = div;
let theFirstChild = parentElement.firstChild;
let newElement = document.createElement("div")
newElement.id = "i-new-eleemnt"
parentElement.insertBefore(newElement, theFirstChild)
}
}
});
<div id="container">
<div id="parent1"></div>
<div id="parent2">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3-parent3">
<div id="child3"></div>
<div id="child4"></div>
</div>
</div>
<div id="parent3">
<div id="child5"></div>
<div id="child6"></div>
</div>
</div>
Using
var container = document.getElementById("container");
var elements = container.querySelectorAll(":scope *");
instead of
var container = document.getElementById("container").querySelectorAll("#container > *");
should fix your problem.
var container = document.getElementById("container");
var elements = container.querySelectorAll(":scope *");
elements.forEach(function(div){
{
if (div.hasChildNodes()) {
let parentElement = div;
let theFirstChild = parentElement.firstChild;
let newElement = document.createElement("div")
newElement.id = "i-new-eleemnt"
parentElement.insertBefore(newElement, theFirstChild)
}
}
});
<div id="container">
<div id="parent1"></div>
<div id="parent2">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3-parent3">
<div id="child3"></div>
<div id="child4"></div>
</div>
</div>
<div id="parent3">
<div id="child5"></div>
<div id="child6"></div>
</div>
</div>
Edit: Further information about the :scope CSS pseudo-class can be found here and here.
I believe your problem is the following, even it is not described well in your sample HTML:
<div id="parent1"></div> per instance is actually not an empty node but contains some text i.e. <div id="parent1">some text here</div>.
You might believe or not, but node.hasChildNodes() will count any text as a child node (text node, nodeType = 3), so it will always return true is any text is present.
To avoid that, you can filter the text nodes first or just use this workaround:
Replace this line:
if (div.hasChildNodes()) {
with that line:
if (div.children.length) {
children property is not counting text nodes.
That's all you have to do, I believe.
var container = document.querySelectorAll("#container > *");
container.forEach(function(div) {
{
if (div.children.length) {
let parentElement = div;
let theFirstChild = parentElement.children[0];
let newElement = document.createElement("div")
newElement.id = "i-new-eleemnt";
newElement.innerHTML = 'i-new-eleemnt'
parentElement.insertBefore(newElement, theFirstChild);
}
}
});
<div id="container">
<div id="parent1">parent1</div>
<div id="parent2">parent2
<div id="child1">child1</div>
<div id="child2">child2</div>
<div id="child3-parent3">child3-parent3
<div id="child3">child3</div>
<div id="child4">child4</div>
</div>
</div>
<div id="parent3">parent3
<div id="child5">child5</div>
<div id="child6">child6</div>
</div>
</div>
I have a div group inside some that I want to have a class for every div that doesn't have a specific element like h1
For Example :
<div class="container">
<div class="parents">
<h1>AAAA</h1>
<div class="content">
<p>Hello</p>
</div>
</div>
</div>
I want to check each div inside some of it and get all the class that does not contain h1 and the result is like
class = 'content'
I'm trying my javascript code via parseFromString because the html code is taken out from string
var My_HTML = `
<div class="container">
<div class="parents">
<h1>AAAA</h1>
<div class="content">
<p>Hello</p>
</div>
</div>
</div>
`;
var parser = new DOMParser();
var doc = parser.parseFromString(My_HTML, "text/html");
var output = doc.querySelectorAll("div:not('div > h1')");
Step 1: Get all div elements.
Step 2: Filter the collection, keeping those that do not have an h1 descendant.
Step 3: For each matching element, map the element to its className property.
Step 4: There is no step 4.
[...document.querySelectorAll('div')].filter(d => !d.querySelector('h1')).map(d => d.className)
const My_HTML = `
<div class="container">
<div class="parents">
<h1>AAAA</h1>
<div class="content">
<p>Hello</p>
</div>
</div>
</div>
`;
const parser = new DOMParser();
const doc = parser.parseFromString(My_HTML, "text/html");
const everyDiv= [...doc.querySelectorAll('div')].filter(d => !d.querySelector('h1')).map(d => d.className);
console.log(everyDiv)
Consider the following.
$(function() {
$(".container *").each(function(i, el) {
console.log("Check Elements", $(el).prop("nodeName"), $(el).attr("class"));
if (!$(el).is("h1")) {
console.log("Class: " + $(el).attr("class"));
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="parents">
<h1>AAAA</h1>
<div class="content">
<p>Hello</p>
</div>
</div>
</div>
This itereates each of the elements within .container; only looking for a Class if it is not an <h1> element.
You could also use the :not() selector.
$(function() {
$(".container *:not(h1)").each(function(i, el) {
console.log("Check Elements", $(el).prop("nodeName"), $(el).attr("class"));
});
});
This will select the child elements that are not H1.
I have the following HTML:
<div class="container">
<h1 class="heading">heading</h1>
<p class="paragraph">test</p>
<h2 class="subheading">123</h2>
<a class="link">321</a>
</div>
How can I wrap the last three elements within .container, so that the output looks like this:
<div class="container">
<h1 class="heading">heading</h1>
<div class="subcontainer">
<p class="paragraph">test</p>
<h2 class="subheading">123</h2>
<a class="link">321</a>
</div>
</div>
It would be better to do it within the HTML, but in case due to some constraints that you can't modify the HTML, you can do the followings
const container = document.querySelector('.container');
const subcontainer = document.createElement('div');
const lastThree = Array.from(container.children).slice(-3);
subcontainer.classList.add('subcontainer');
// move the elements into the subcontainer
lastThree.forEach(node => {
subcontainer.appendChild(node);
});
container.appendChild(subcontainer);
<div class="container">
<h1 class="heading">heading</h1>
<p class="paragraph">test</p>
<h2 class="subheading">123</h2>
<a class="link">321</a>
</div>
The class name container is quite generic, make sure that you only select the container element you want, or else you might modify other elements unintentionally.
old_html = document.getElementsByClassName("container")[0];
firstChild = old_html.children[0];
old_html.removeChild(firstChild);
new_html = "<div class='container'>"+ firstChild.outerHTML + "<div class = 'subcontainer'>" + old_html.innerHTML + "</div></div>";
console.log(new_html);
<div class="container">
<h1 class="heading">heading</h1>
<p class="paragraph">test</p>
<h2 class="subheading">123</h2>
<a class="link">321</a>
</div>
Hullo, I am wondering how I can add a new link around/to an element, using only JavaScript? I am new to JavaScript, and I am sorry if this question seems stupid or too easy.
Current:
<div class="container">
<div class="content1"></div>
<div class="content2"></div>
</div>
Desired Code:
<div class="container">
<div class="content1"></div>
<a href="http://example.com">
<div class="content2"></div>
</a>
</div>
Just use normal DOM manipulation, nothing tricky required
const container = document.querySelector('.container');
const a = container.appendChild(document.createElement('a'));
a.href = "http://example.com";
a.appendChild(document.querySelector('.content2'));
console.log(container.innerHTML);
<div class="container">
<div class="content1"></div>
<div class="content2"></div>
</div>
Can use jQuery wrap()
$('.content2').wrap('<a href="http://example.com">')
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="content1">content 1</div>
<div class="content2">content 2</div>
</div>
Create a new a element and create a child in that element with the same content in your div and append the a element in the parent of the old div('.container')
var content2 = document.getElementsByClassName('content2')[0];
var container = content2.parentNode;
var a = document.createElement('a');
a.setAttribute("href", "www.google.com");
container.replaceChild(a, content2);
a.appendChild(content2);
<div class="container">
<div class="content1">Content1</div>
<div class="content2">Content2</div>
</div>
Using only pure Javascript, you can do something like this:
1. get your div by class (you can do using getElementById if you define an id for your div)
var mydiv = document.getElementsByClassName('content1');
2. create your anchor and set an href
var new_anchor = document.createElement("a");
new_anchor.href = "http://example.com";
3. Place the div content1 inside new anchor
new_anchor.append(mydiv[0]);
4. Place your entire element inside the container again
var mycontainer = document.getElementsByClassName('container');
mycontainer[0].insertBefore(new_anchor, mycontainer[0].childNodes[0])
<div id="inst4" class="block_navigation block">
<div class="content">
<div> Content Start here !!!</div>
</div>
</div>
<script>
var blockNav = document.getElementsByClassName("block_navigation")[0].getElementsByClassName("content");
blockNavIcon = document.createElement("img");
blockNavIcon.setAttribute("src", blockIcon);
blockNav.appendChild(blockNavIcon);
}
</script>
Here I am targeting content class, but it is not working, How can i do this any solution.
There are few problems in your script, you are using the class block_navigation twice, also blockNav is a NodeList
You can easily use .querySelector()
var blockNav = document.querySelector(".block_navigation .content");
blockNavIcon = document.createElement("img");
blockNavIcon.setAttribute("src", '//placehold.it/64');
blockNav.appendChild(blockNavIcon);
<div id="inst4" class="block_navigation block">
<div class="content">
<div>Content Start here !!!</div>
</div>
</div>
You can use use .getElementsByClassName("content")[0]
Hope this wil be helpful
var blockIcon = "http://weknowyourdreams.com/images/forest/forest-04.jpg";
var blockNav = document.getElementsByClassName("block_navigation")[0]
.getElementsByClassName("content")[0]; // Will select the child element
blockNavIcon = document.createElement("img");
blockNavIcon.setAttribute("src", blockIcon);
blockNav.appendChild(blockNavIcon)
JSFIDDLE