From my understanding, document.querySelector returns a Node object. I can then call appendChild on this object.
I execute the following code to append a bunch of divs to my container div:
var container = document.querySelector('.container');
for (var i = 0; i < 400; i++) {
var block = document.createElement('div');
block.className = 'block';
container.appendChild(block);
}
And end up with the following structure:
<div class="container">
<div class="block"></div>
<div class="block"></div>
...
<div class="block"></div>
</div>
How can I loop through each element in my container div and add a new class to it using my existing container variable?
I have tried this:
...
container.childNodes[i].className = 'myClass';
It seems I need to access the Element object of the child Node, but I'm not sure how to do this.
Can you not just add it when you create the divs ?
var container = document.querySelector('.container');
for (var i = 0; i < 400; i++) {
var block = document.createElement('div');
block.className = 'block myClass';
container.appendChild(block);
}
To add classes to the elements in the container variable, I used the following code:
container.children[i].className = 'myClass';
I had to use children instead of childNodes. You can see the context in which this code was used here: http://codepen.io/robkom/pen/RWmodz.
Related
Can i use query selector to find dynamically created elements that have an attribute?
I want to find the first element with val, but this won't find them. (divs with the values a-d are there just to show this works with "normally" created elements.)
let i = 4, wrapper = document.getElementsByClassName("wrapper")[0];
while (i-- > 0) {
let div = document.createElement("div");
div.val = i;
wrapper.appendChild(div);
}
let myDiv = document.querySelector(".wrapper div[val]");
console.log("myDiv", myDiv);
<div class="wrapper">
</div>
<div class="wrapper">
<div val="a"></div>
<div val="b"></div>
<div val="c"></div>
<div val="d"></div>
</div>
Use Element.setAttribute() to set the attributes so they can be found by the querySelector:
let wrapper = document.getElementsByClassName('wrapper')[0]
let i = 4
while (i--) {
let div = document.createElement('div')
div.setAttribute('val', i)
wrapper.appendChild(div)
}
let myDiv = document.querySelector('.wrapper div[val]')
console.log('myDiv', myDiv)
<div class="wrapper"></div>
This question already has an answer here:
Append Div with Multiple Child Divs Using For Loop
(1 answer)
Closed 1 year ago.
I want to append the HTML child_element div multiple times as defined on variables inside the parent_element using Javascript on DOM Load.
Desire Output:
<div class="parent_element">
<div class = "child_element">
<div class = "child_element">
<div class = "child_element">
<div class = "child_element">
<div class = "child_element">
</div>
You can create a child node object and append it to the parent node in loop. Since you have multiple child nodes to be appended you can use DocumentFragment
const parentNode = document.createElement('div');
parentNode.classList.add('parent_element');
const childNode = document.createElement('div');
childNode.classList.add('child_element');
const fragment = new DocumentFragment();
for(let i=0; i<[*no_of_times_you_want_child_node*]; i++) {
fragment.appendChild(childNode.cloneNode(true));
}
// finally append dom fragment to parent
parentNode.appendChild(fragment);
Assuming that you want the number of children to be defined by an attribute "variables inside the parent_element"
<div class="parent" children="5"></div>
<script>
const parentEl = document.querySelector(".parent");
const numOfChildren = +parentEl.getAttribute("children");
const fragment = new DocumentFragment();
for (let i=0; i<numOfChildren; i++) {
const childEl = document.createElement("div");
childEl.classList.add("child");
fragment.appendChild(childEl);
}
parentEl.append(fragment);
</script>
The basic process is:
Get a reference to the parent element using the class selector
Retrieve the number of children you want from the attribute named children. This is a string value so the + will convert it to a number
Loop through the creation of a new element on the DOM adding the desired class name before appending the child.
Edit: As per pilchard's suggestion I've merged in DocumentFragment from abhishek khandait's answer.
You can dynamically add a new div element using jquery.
<script>
function addNewDivElement() {
$("#parent_element").append('<div class = "child_element">')
}
</script>
the function addNewDivElement can be called on click of a button. something like below:
<button onclick="addNewDivElement()">
Add
</button>
I am making a gallery. All images are named 1.jpg, 2.jpg, 3.jpg etc - it extends all the way up to 200.jpg.
Copy and paste will be OK, but very time consuming.
<div class="slideshow-container">
<div class="slideshowDisplay fade">
<img src="/images/media/1.jpg" width="100%">
</div>
<div class="slideshowDisplay fade">
<img src="/images/media/2.jpg" width="100%">
</div>
<div class="slideshowDisplay fade">
<img src="/images/media/3.jpg" width="100%">
</div>
Can I use a for-loop or similar to create all the elements for me? My only problem is that, a for loop is used to repeat a code block multiple times is it not, so this for me wouldn't work.
Is there another way that I can create elements without having to spend a long time simply incrementing numbers by hand?
So far I have:
for(var i=0; i < 200; i++){
var newDiv = document.createElement('div');
newDiv.className = 'slideshowDisplay fade';
}
Nothing else...
Any guidance much appreciated.
Basic DOM creation and appending
You're only missing appending the new element to the slideshow-container and adding its content. You can use the i variable to create the increment image src.
var sc = document.querySelector(".slideshow-container")
for(var i=0; i < 200; i++){
var newDiv = sc.appendChild(document.createElement('div'));
newDiv.className = 'slideshowDisplay fade';
var img = newDiv.appendChild(document.createElement("img"));
img.width="100%";
img.src = "/images/media/" + (i + 1) + ".jpg";
}
String concatenation
The means of creating the src is called "string concatenation". In other words, we create a new string from multiple parts. First the "/images/media/" string, then the value of i, but adjusted up by one, and finally the ".jpg" part.
Making helper functions
FWIW, it's nice to have a personal micro-library that you use to handle certain repetitive tasks. One such inclusion can be a function for creating new Elements.
function create(elem, props, par) {
var el = document.createElement(elem)
for (var p in props) {
el[p] = props[p]
}
return par ? par.appendChild(el) : el
}
This takes a little verbosity out of creating and appending the new elements.
var sc = document.querySelector(".slideshow-container")
for(var i=0; i < 200; i++){
var newDiv = create("div", {className: "slideshowDisplay fade"}, sc);
create("img", {width: "100%", src: "/images/media/"+(i+1)+".jpg"}, newDiv);
}
Different approach to a helper function
Or instead of having the function receive the parent to which it is appended, you could allow it to receive an arbitrary number of child elements that it will append to itself.
function create(elem, props, ...children) {
var el = document.createElement(elem)
for (var p in props) {
el[p] = props[p]
}
children.forEach(ch => el.appendChild(ch))
return el
}
Then you can nest calls to create in a way that mirrors the new DOM structure.
var sc = document.querySelector(".slideshow-container")
for(var i=0; i < 200; i++){
sc.appendChild(
create("div", {className: "slideshowDisplay fade"},
create("img", {width: "100%", src: "/images/media/"+(i+1)+".jpg"})
)
);
}
Actually you need just one parent div in your DOM. Then just use functions like document.createElement and appendChild to store the newly created divs with pictures inside the parent element.
var source = "/images/media/";
var parent = document.getElementById('parent');
for (var i = 0; i < 10; i++) {
var newDiv = document.createElement('div');
newDiv.className = 'slideshowDisplay fade';
var img = document.createElement('img');
img.src = source + i + '.jpg';
img.width = '100%';
newDiv.appendChild(img);
parent.appendChild(newDiv);
}
<div class="slideshow-container" id='parent'>
</div>
I have a set of elements and want to remove its container wrapper in Javascript.
I've researched around (this, this, and this) but I need a solution that 1) doesn't involve jQuery. 2) and can work on multiple elements.
HTML:
<div class="global-container stacked">
<article class="global"></article>
<article class="global"></article>
</div>
I've tried:
var globalArticles = document.getElementsByClassName('global');
globalArticles.outerHTML = globalArticles.innerHTML;
But that doesn't work. How would one go about removing the wrapper from all article.global?
You could just create your own unwrap() method, something like this
function unwrap(elems) {
elems = 'length' in elems ? elems : [elems];
for (var i = 0; i < elems.length; i++) {
var elem = elems[i];
var parent = elem.parentNode;
var grandparent = parent.parentNode;
grandparent.insertBefore(elem, parent);
if (parent.children.length === 0)
grandparent.removeChild(parent);
}
}
var globalArticles = document.getElementsByClassName('global');
unwrap(globalArticles);
You can use .innerHTML, .removeChild(), .insertAdjacentHTML()
var container = document.querySelector(".global-container");
var html = container.innerHTML; // store `html` of `container`
container.parentElement.removeChild(container); // remove `container`
document.body.insertAdjacentHTML("beforeend", html); // append `html`
<div class="global-container stacked">
<article class="global">1</article>
<article class="global">2</article>
</div>
This should work:
var globalArticle = document.getElementsByClassName('global')[0];
if (globalArticle) {
globalArticle.parentElement.outerHTML = globalArticle.parentElement.innerHTML;
}
So I have the following HTML...
HTML:
<div id="col1">
<img src="1.jpg">
</div>
And I am implementing a HTML5 drag and drop feature where the inner html of col1 is changed for the dragged element's inner html - so basically the columns change their content.
I have another div (let's call that swap-text) where I want to change its text content depending on what image is presently inside col1.
This is why I want to figure out how I can obtain col1's img element's src attribute value through JavaScript so I can then write an if statement to change the content of the swap-text depending on which image is in col1.
I could add ID's to the img elements but then I still don't know how I would write the condition to check if say, img-id1 parent is col1.
Attempt(s):
var doc = document.getElementById("col1");
var children = null;
var imgEle;
//gets img node, but also got 1/2 text object(s)?
for (var i = 0; i < doc.childNodes.length; i++) {
children = doc.childNodes[i];
console.log(children);
}
//document.getElementById("img")
//children[1].getAttribute('src'); - cannot call method 'getAttribute' of undefined
//imgEle = doc.childNodes[0].getElementById('img'); - Object #<Text> has no method 'getElementById'
console.log(imgEle);
console.log(children);
This work fine pure javascript:
document.getElementById("col1").getElementsByTagName("img")[0].getAttribute("src");
var doc = document.getElementById("col1");
var img = document.getElementsByTagName('img')[0];
var imgParent = img.parentElement;
This is how you determine the elements parent/
I suggest you to use JQuery so you can simply use:
$("img").attr("id"); //Return the id of the img element
Check this:
var column = document.getElementById("col1");
var imgSrc = column.getElementsByTagName("img")[0].getAttribute("src");
Or just use the jQuery - it's simpler:
$('#col1 img').attr('src');
as you will only have one child node in col1 (the img), change the for loop.
var doc = document.getElementById("col1");
var children = null;
var imgEle;
//gets img node, but also got 1/2 text object(s)?
//for (var i = 0; i < doc.childNodes.length; i++) {
// children = doc.childNodes[i];
// console.log(children);
//}
childen = doc.childNodes[0];
// or children = doc.firstChild;
console.log(children);
//document.getElementById("img")
console.log(children.getAttribute('src')); - children is single object
//imgEle = doc.childNodes[0].getElementById('img'); - Object #<Text> has no method 'getElementById'
console.log(imgEle);
console.log(children);