DOM Manipulation for parent and child div at the same time - javascript

My HTML:
<div id="parent">
<ul id="child"></ul>
</div>
<button>click</button
My JS:
var parent = document.getElementById('parent');
var child = document.getElementById('child');
var button = document.querySelector('button');
button.addEventListener('click', function(){
parent.innerHTML = 'value1';
child.innerHTML = 'value2';
});
I am trying to add values via JS for the parent and child div. But when I click button the nested ul tags disappear and my DOM only shows the parent value. Trying to understand what is happening here. Is this a flaw in the way I have structured the HTML? If this is expected behavior, how can I fix it without changing the HTML tags relationship?
Expected result should be: value1 and value2. Right now it only shows value1.

That's because you are overwiting instead of appending.
If you want to add to an already existing element, you should be using append() and appendChild() instead.
What .innerHTML does is transcribing the markup to a new one (which means obviously over-writing any previously contained markup).
In summary, your code does work as expected. The issue is, you are trying to apply one method, while trying to achieve something different.

This is expected.
innerHTML replaces the insides of the element, thus, the child would not exist

Also you can use HTML DOM insertAdjeacentHTML() Method instead of innerHTML for parent element. This method inserts a text as HTML, into a specified position. Legal position values are: "afterbegin", "afterend", "beforebegin" and "beforeend".
var parent = document.getElementById( 'parent' ),
child = document.getElementById( 'child' ),
button = document.querySelector( 'button' );
button.addEventListener( 'click', function() {
parent.insertAdjacentHTML( 'afterbegin', 'value1' );
child.innerHTML = 'value2'
} )
<div id="parent">
<ul id="child"></ul>
</div>
<button>click</button>

Related

Display outerHTML of multiple elements when the element is created by user

I have a JavaScript program that will create an element each time a button is pressed.
I use:
var element = document.createElement("div");
element.innerHTML = "hi";
document.body.appendChild(element);
I want to make it so when a user creates an element by clicking the button, then it will generate the element's html code or the outerHTML. But I also want it to do this if the user clicked the first button multiple times. So that means that I want it to generate the outer html for every element they make when they push the button. For this, I use:
function CreateElement() {
var element = document.createElement("div");
element.innerHTML = "hi";
document.body.appendChild(element);
var code = element.outerHTML;
}
However, the problem is that there are multiple elements that were created that were under the variable "element". So I want the, "code" variable to contain the outerHTML of all of the elements. I've tried:
function createElement() {
var code = element.outerHTML;
code = code + element.outerHTML //will add the outer html to the variable each time a new element is created
}
...but it always just replaces the whole variable instead of adding the outerhtml to the variable each time the button is clicked to make an element. My goal is to make the variable "code" look something like "<div>hi</div> <div>hi</div>" (as a string)
Thanks for any help
Append each dynamic element into a single container, then take that container's innerHTML:
const container = document.querySelector('.container');
const button = document.querySelector('button');
function createElement() {
var element = document.createElement("div");
element.textContent= "hi";
container.appendChild(element);
console.log(container.innerHTML);
}
button.onclick = createElement;
<button>click</button>
<div class="container"></div>
Also, just a suggestion regarding element.innerHTML = "hi"; - best to only use innerHTML when deliberately setting or retrieving HTML markup. If you just have text, it's faster, safer, and more appropriate to use .textContent.

Inserting div into existing div with class only

I'm trying to create a new div in Javascript with two spans in it, each containing a string of text. They are then meant to be inserted before div.two in div.inner.
The div I'm trying to insert it into only has a class and I cannot target it by any ID, unfortunately.
I have also created a codepen here: https://codepen.io/lisaschumann/pen/BXqJKY
Any help is massively appreciated!
HTML
<html>
<div class="inner">
<div class="one"></div>
<div class="two"></div>
</div>
</html>
JS
window.onload=function(){
var infobox = document.createElement("div");
infobox.classList.add('infobox');
var spanOne = document.createElement("div");
var spanOneText = document.createTextNode('Important text 1');
var spanTwo = document.createElement("div");
var spanTwoText = document.createTextNode('Important text 2');
spanOne.appendChild(spanOneText);
spanTwo.appendChild(spanTwoText);
infobox.appendChild(spanOne);
infobox.appendChild(spanTwo);
var targetDiv = document.getElementsByClassName("inner");
targetDiv.insertBefore(infobox, targetDiv.childNodes[1]);
}
Errors:
Cannot read property '1' of undefined
at window.onload
The main issue is that getElementsByClassName returns a live collection of nodes rather than one node and so you would need to access the correct node in that list similar to an array: targetDiv[0], perhaps.
The easier method is to use querySelector to grab the element you want using its class, for example:
var parent = document.querySelector(".inner");
var two = document.querySelector(".two");
parent.insertBefore(infobox, two);
But! there's even a shortcut method you can use here that allows you to add an HTML string direct to the DOM which might save you a bit of time, and some code.
// Create the HTML
const html = `
<div>
<span>Text alpha</span>
<span>Text beta</span>
</div>`;
// Grab the element containing your "two" class
const two = document.querySelector('.inner .two');
// Using insertAdjacentHTML to add the HTML before the two element
two.insertAdjacentHTML('beforebegin', html);
<div class="inner">Inner
<div class="one">one</div>
<div class="two">two</div>
</div>
insertAdjacentHTML
This doesn't work because of these lines
var targetDiv = document.getElementsByClassName("inner");
targetDiv.insertBefore(infobox, targetDiv.childNodes[1]);
document.getElementsByClassName returns a NodeList. targetDiv.childNodes is undefined, because childNodes doesn't exist on a NodeList.
You need to either use a list operation like Array.prototype.forEach, change getElementsByClassName to getElementByClassName (note the s) or access the first node in the node list using the array indexer syntax.
I assume you meant to do something like this:
var targetDiv = document.getElementByClassName('inner')
targetDiv.insertBefore(infobox, targetDiv.childNodes[1])
This will insert a node in between the first and second child of the first DOM node with the class inner.
Try this out , targetDiv is an array by default due to the getElementsByClassName method , even though it has a single element.Hence you need to specify the index i.e. 0 ( as it's the first element of the array)
var targetDiv = document.getElementsByClassName("inner")[0]; targetDiv.insertBefore(infobox, targetDiv.children[1]); }
Using JQuery
$(document).ready(function(){
$(`<div>Important text 1<span></span>Important text 2<span></span></div>`).insertBefore( ".inner .two" );
)
I would encourage you to use JQuery and then shift to vanilla javascript later on. You can do simple tasks like this in just few lines of code and it is also easily debuggable because of that

Removing and creating HTML elements with same id using Javascript

I have a button that, when pressed, executes something like
function click(){
element = document.getElementById("element");
element.parentNode.removeChild(element);
var newelement = document.createElement("div");
body.appendChild(newelement);
newelement.id = "element";
}
I have also tried using element.outerHTML = "" instead of removeChild with no success. Before adding the bit about deleting the previous element with the id "element" things worked fine on the first click and an div named "element" was appended to the body. (Of course, on the second click, another element named "element" is appended, and I want to keep the id unique to one element.) Now, with the bit about removing previous elements, my button.onClick doesn't even do anything.
Another important piece of context: I'm trying to do this for elements that are generated using user input, so there's no guarantee on how many of these things are made--I just want them deleted when the user wants to generate more of them.
On the first click, I'm attempting to remove an empty element. Does that break something?
body does not exist in the scope you've provided and would throw an exception. I would try:
var body = document.querySelector("body");
See this for a example using your code:
https://jsfiddle.net/k0wL4y7p/2/
Also make sure you use var on all local variables so they are not declared globally. See below to learn about variable scope:
When to use var in Javascript
How about this... don't remove the Parent Element (Div1); instead to remove the children. Then, create the child and append it to the parent element.
Note: you must iterate over it to remove all child nodes & for p element id p1/p2 generate dynamic id or use class if you need it.
Your JS:
$(document).ready(function() {
$("#btn1").click(function() {
var element = document.getElementById("div1");
while (element.firstChild) {
element.removeChild(element.firstChild);
}
var para = document.createElement("p");
var node = document.createTextNode("New element after click.");
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
});
});
I prefer JQuery - no loop
$(document).ready(function(){
$("#btn1").click(function(){
$("#div1").empty();
$("#div1").append(" <p>Appended element after click</p>");
});
});
Your Html
<body>
<div id="div1">
<p id="p1">Paragraph element before click.</p>
<p id="p2">Another paragraph beofre click.</p>
</div>
<button id="btn1">Remove </button>
</body>
Hope it helps.

Append a whole element which has children and grand children to another element using pure js

This is my placeholder div..
<div id="placeholderDiv">
</div>
This is my another div from which i have to get all the elements inside it
<div id="targetel">
<div id="targetelInner">
one
two
three
</div>
</div>
Now i need to get all the elements which are inside the id="targetel" and want to insert in to the id="placeholderDiv". and my final output should be
<div id="placeholderDiv">
<div id="targetelInner">
one
two
three
</div>
</div>.
how can I code this using js..? and i write the html code in html document.. and not as a js file..
This will retain the state of the elements that were in targetel and instead of copying the HTML markup, it transfers possession of the actual node objects. Event listeners and other data will be kept on the elements transferred.
var placeholder = document.getElementById('placeholderDiv');
var targetel = document.getElementById('targetel');
var frag = document.createDocumentFragment();
while (targetel.firstChild) {
frag.appendChild(targetel.removeChild(targetel.firstChild));
}
placeholder.appendChild(frag);
just put the innerHTML of targetel to placeholderDiv
document.getElementById( "placeholderDiv" ).innerHTML = document.getElementById( "targetel" ).innerHTML;
if you want this to happen at onload event of the page then add this to your HTML page
<script>
window.load = function(){
document.getElementById( "placeholderDiv" ).innerHTML = document.getElementById( "targetel" ).innerHTML;
}
</script>
and remove items inside targetel by
document.getElementById( "targetel" ).innerHTML = "";
There are many ways to achieve this. One of which, and probably the cleanest is to first get your element.
var element= document.getElementById('targetelInner');
Then create a clone of it. Note that specifying true in cloneNode will make it a deep clone, thus also cloning it's children.
var elClone= element.cloneNode(true);
After which you simply append the new cloned div.
document.getElementById('placeholderDiv').appendChild(elClone);
Note that append child will add this node as the last child of the placeholder, and not remove any contents it already has.

How to get attributes values separately for each container present on the webpage in jquery?

This question is in continuation to How to get attributes of container in jQuery, I have different containers on my webpage and all of them have <div id = "some values">. Now how can I get attributes values separately for each component?
Is there any way I can know which attribute id belong to which container div?
Currently I am using:
var id = $( '.promotion' ).attr( 'id' );
But if I have multiple promotional components on page and all have same div attribute as id than how can I relate that this particular attribute id belonged to this specific container?
Update: I am having a function which is called for each container present on the page and so if I am using above mentioned code than will it not always return me the first match for id in the div and would never go to other divs and so I will always get same value for id which is for the first container ? If so than what is the work around for this ?
var id = $( '.promotion' ).this.attr( 'id' );
var id = $( '.promotion' ).$this.attr( 'id' );
var id = this.$( '.promotion' ).attr( 'id' );
How would I know if the attribute value is for current container, so how should I use this properly to get this information ?
Hope this question is clear.
You can loop through and process each div individually
$(".promotion").each(function() {
var id = this.id; // 'this' is the html element, not the jquery object
});
Update
function myfunc() {
alert(this);
}
// inside myfunc, this will be the window
myfunc();
// call (also: apply()) changes "this" to be the first argument
myfunc.call(document.getElementById("someid"));
Jquery uses this to refer to the current element being processed. In events that would be the target element. In .each it is the current element in the collection.
Consider:
$(".promotion").click(function() {
alert(this); // will alert with the div that was clicked
});
In Jquery you can wrap any html element with a JQuery Object by using $(element). So when this is an html element like in the example above you can use $(this):
$(".promotion").click(function() {
alert($(this).attr("id")); // will alert with the div that was clicked
});
Play around with it here: http://jsbin.com/okuri3/edit.
More about this:
http://www.quirksmode.org/js/this.html
http://remysharp.com/2007/04/12/jquerys-this-demystified/

Categories

Resources