Javascript replace parent html (remove child) - javascript

I would like loop each iframes tags I've on my page and replace them all with a new div and on the way delete also the parent content so the new div will be the only child:
<div id="parent">
<p>this is parent content</p>
<iframe src="http://www.example.com" id="iframe10"></iframe>
</div>
Result should be:
<div id="parent">
<div id="newdiv">this is new div</div>
</div>
Here is my code for looping all iframes on page, the problem I don't understand how I can access each iframe parent and delete its contents:
var i, frames;
frames = document.getElementsByTagName("iframe");
for (i = 0; i < frames.length; ++i)
{
frame_id = frames[i].id;
}
Thanks
Shai

you can write it as following:
function remove_frames() {
var i = 0;
var frames = document.getElementsByTagName("iframe");
while (frames.length > 0) {
var f = frames[0];
var p = f.parentElement;
if (p) {
while (p.children.length > 0) {
p.children[0].remove();
}
p.innerHTML = "<div id=\"newdiv" + i + "\">this is new div" + i + "</div>";
i++; //increase id index
//p.appendChild(
}
}
}
<p><input type="button" value="Execute" onclick="remove_frames()" /></p>
<div id="parent">
<p>this is parent content</p>
<iframe src="http://www.example.com" id="iframe10"></iframe>
</div>
<p style="color:#6595ee">This element does not contain any sibling IFrame and must be exist in final result!</p>
<div id="parent2">
<p>this is parent2 content...</p>
<div>another element</div>
<iframe src="http://www.example.com" id="iframe20"></iframe>
<p>another element after iframe.</p>
</div>

var i, frames;
frames = document.getElementsByTagName("iframe");
for (i = frames.length; i; --i) // the array-like object shrinks every time a frame is removed so we have to loop backwards
{
//frame_id = frames[i].id;
// get the parent element
var parent = frames[i].parentElement;
// empty it (remove all it's elements)
while(parent.firstChild)
parent.removeChild(parent.firstChild);
// add the new div
var div = /* create new div */;
parent.appendChild(div);
}

You could use the parentElement
var iframes = document.getElementsByTagName("iframe");
iframes[0].parentElement.innerHTML = `<div id="newdiv">this is new div</div>`;
<div id="parent">
<p>this is parent content</p>
<iframe src="http://www.example.com" id="iframe10"></iframe>
</div>

You can use Node.parentNode to get the parent and Node.removeChild or Element.innerHTML to delete the content.
var i, frames;
frames = document.getElementsByTagName("iframe");
for (i = frames.length-1; i >=0; i--) {
var frame = frames[i];
if (frame.parentNode) {
var parent = frame.parentNode;
while (parent.firstChild) {
parent.removeChild(parent.firstChild);
}
}
}
<div id="parent">
<p>this is parent content</p>
<iframe src="http://www.example.com" id="iframe10"></iframe>
</div>

Related

AppendChild in for loop adds every second child?

I need to wrap children element in wrap-of-parent. Before wraping add some attributes to parent and child elements. In the code described below, everything works well if the children are one below the other in a separate row, and if they are in one row, every other child is inserted into the wrap-of-parent. Why is this happening and how to fix it?
I get:
<div id="container">
<div id="parent1">
<div id="child1"></div>
<div id="child2"></div>
<div id="wrap-of-parent1">
<div id="child3"></div>
<div id="child4"></div>
</div>
</div>
I need to get:
<div id="container">
<div id="parent1">
<div id="wrap-of-parent1">
<div id="child1"></div>
<div id="child2"></div>
<div id="child3"></div>
<div id="child4"></div>
</div>
</div>
Code:
var container = document.getElementById("container");
const parentDivs = container.querySelectorAll(":scope *"); //if child elements also have child elements, to wrap in
for (let parent of parentDivs) {
// create a new div
let wrap = document.createElement('div');
wrap.id = 'wrap-of-' + parent.id;
// move the parent's children to it
let children = parent.childNodes;
for (let i = 0; i < children.length; i++) {
if (children[i].nodeType === Node.ELEMENT_NODE) {
children[i].setAttribute("data", "somedata");
wrap.append(children[i]);
}}
// and append it to the parent
parent.appendChild(wrap);
}
<div id="container">
<div id="parent1">
<div id="child1"></div><div id="child2"></div><div id="child3"></div><div id="child4"></div>
</div>
</div>
<! - If the child elements are one below the other in a separate row it works, if they are in one row it does not work ->
If you keep moving the first (index 0) entry, it will work. You need to add an offset when the wrong nodeType is encountered to skip over those ones, and if there are no child nodes then don't process the node:
var container = document.getElementById("container");
const parentDivs = container.querySelectorAll(":scope *"); //if child elements also have child elements, to wrap in
for (let parent of parentDivs) {
// create a new div
if (parent.childNodes.length > 0) {
let wrap = document.createElement('div');
wrap.id = 'wrap-of-' + parent.id;
// move the parent's children to it
let children = parent.childNodes;
const nChildren = children.length;
let offset = 0;
for (let i = 0; i < nChildren; i++) {
if (children[offset].nodeType === Node.ELEMENT_NODE) {
children[offset].setAttribute("data", "somedata");
wrap.append(children[offset]);
} else {
offset++;
}
}
// and append it to the parent
parent.appendChild(wrap);
}
}
<div id="container">
<div id="parent1">
<div id="child1"></div><div id="child2"></div><div id="child3"></div><div id="child4"></div>
</div>
</div>

childNode unexpected behaviour

Scenario
I would like to get all child nodes of my div and change it color.
Code:
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.childNodes;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
myCollection[i].style.color = "red";
}
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
Error:
This is not working. It seems tha in my collection i have all nodes. h2 p text buton. I Expeceted just p h2 and buton.
EDIT
Explanation
Note: Whitespace inside elements is considered as text, and text is considered as nodes. Comments are also considered as nodes.
So we need to check if node is element node, or use querySelectorAll.
Examples in answers below. Thanks for your help.
Text nodes do not have style attributes. If you want to use childNodes, check that the nodeType is 1 (an Element node) first:
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.childNodes;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
if (myCollection[i].nodeType === 1) myCollection[i].style.color = "red";
}
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
But I would prefer using querySelectorAll and forEach here:
function myFunction() {
document.querySelectorAll('#divv > *')
.forEach(child => child.style.color = "red");
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
(or, you could simply set #divv's style.color to red)
You could use the children property to access the children of a given node:
The ParentNode property children is a read-only property that returns a live HTMLCollection which contains all of the child elements of the node upon which it was called.
- MDN web docs
function myFunction() {
var divv = document.getElementById("divv");
var myCollection = divv.children;
var len = myCollection.length;
var i;
for (i = 0; i < len; i++) {
myCollection[i].style.color = "red";
}
}
<div id="divv">
<h2>JavaScript HTML DOM</h2>
<p>Hello World!</p>
<p>Hello Norway!</p>
<p>Click the button to change the color of all p elements.</p>
<button onclick="myFunction()">Try it</button>
</div>
Another way to do with ES6 would be to spread the child nodes into an array and loop through them with a .forEach:
const myFunction = () => {
[...document.querySelector('#divv').children].forEach(child => {
child.style.color = 'red';
});
}
<div id="divv">
<div class="child">
I am a child
</div>
<div>
<div class="grandchild">
I am a grand child
</div>
</div>
<button onclick="myFunction()">Try it</button>
</div>
Alternatively, you could use the .forEach from the NodeList class directly but the previous method gives you more freedom to work with Array's method such as .reduce, .map, etc...
const myFunction = () => {
document.querySelectorAll('#divv > *').forEach(child => {
child.style.color = 'red';
});
}
<div id="divv">
<div class="child">
I am a child
</div>
<div>
<div class="grandchild">
I am a grand child
</div>
</div>
<button onclick="myFunction()">Try it</button>
</div>

add div using appendChild

This code is supposed to be looping and adding multiple divs, but it isn't working. When I click it, only one div appears. If I click again, nothing happens.
<body>
<div class="start" >
<div id = "coba">
</div>
<div id = "cobi">
</div>
</div>
<script>
var divs = document.getElementById("coba").addEventListener("click", function () {
for (var i = 1; i < 100; i++) {
var di = document.createElement('div');
document.getElementById('coba').appendChild(di);
}
});
</script>
</body>
Thanks for your help
Your code does not work because you did not do anything with the variable "i" in the for statement. If you look at the fiddles of user2181397 & meghan Armes you will see how they added a line in the script to put it to work.
I tested the below in my IDE and it works just fine:
<body>
<div class="start" style="margin-top:50px; color:black;">
<div id = "coba">
<p>Click Me</p>
</div>
<div id = "cobi">
</div>
</div>
<script>
var divs = document.getElementById("coba").addEventListener("click", function() {
for (var i = 1; i < 100; i++) {
var di = document.createElement('div');
di.innerHTML=i;
document.getElementById('coba').appendChild(di);
}
});
</script>
</body>

javascript onclick get the div id?

Is it possible to get the ids of the 2 div tags on clicking the button, using javascript?
<div id="main">
<div id="content">
</div>
<button onclick="function();">show it</button>
</div>
I have 2 div tags here. The 1st div is in the main div while the content div is inside the main div and the button is inside the main div as well.
Is it possible to get the main and content id of the 2 div tags on clicking the button?
EXPECTED OUTPUT when I press the button:
alert: main
alert: content
You need to pass the element to the function. Then you can use parentNode to get the DIV that contains the button. From there, you can use querySelector to find the first DIV in the parent.
function showIt(element) {
var parent = element.parentNode;
alert(parent.id);
var content = parent.querySelector("div");
alert(content.id);
}
<div id="main">
<div id="content">
</div>
<button onclick="showIt(this);">show it</button>
</div>
<div id="main2">
<div id="content2">
</div>
<button onclick="showIt(this);">show it</button>
</div>
<div id="main3">
<div id="content3">
</div>
<button onclick="showIt(this);">show it</button>
</div>
document.getElementById('button').onclick = function () {
var divs = document.querySelectorAll('div');
for (var i = 0; i < divs.length; i++) {
var id = divs[i].getAttribute('id');
alert(id);
}
};
http://jsfiddle.net/jm5okh69/1/
This should work in all browsers and uses the cleaner .id method.
var button = document.getElementById('button');
button.onclick = getIDs;
function getIDs(){
var id,divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
id = divs[i].id // .id is a method
alert(id);
}
}
<div id="main">
<div id="content"></div>
<button id="button">show it</button>
</div>

use innerHTML to select class only if it is in a parent div

i currently have the code below which searches for the class and will replace the text.
how would i tweak it so it only will replace text if the parent tag is "#thumb-hockey-top"?
window.onload = function(){
//this captures all the elements with the spec classes
var soldItems = document.getElementsByClassName('product-mark sold-out');
//this changes each element 1 by 1 to new text
for(var i=0; i<soldItems.length; i++){
soldItems[i].innerHTML = "Coming Soon";
}
}
window.onload = function(){
//this captures all the elements with the spec classes
//just use a class
var soldItems = document.getElementsByClassName('sold-out');
//this changes each element 1 by 1 to new text
//var parentnode = document.getElementById('thumb-hockey-top')
for(var i=0; i<soldItems.length; i++){
if(soldItems[i].parentNode.id=='thumb-hockey-top'){
soldItems[i].innerHTML = "Coming Soon";
}
}
};
<div id="thumb-hockey-top">
<div class="product-mark sold-out"></div>
<div class="product-mark sold-out"></div>
<div class="product-mark sold-out"></div>
</div>
Use once
window.onload = function(){
//this captures all the elements with the spec classes
var soldItems = document.getElementById("thumb-hockey-top").getElementsByClassName('product-mark sold-out');
//this changes each element 1 by 1 to new text
for(var i=0; i<soldItems.length; i++){
soldItems[i].innerHTML = "Coming Soon"
}
}
<div id="thumb-hockey-top">
<div class="product-mark sold-out"></div>
</div>
<div class="product-mark sold-out"></div>
<div class="product-mark sold-out"></div>
Use multiple times
function myF(a, b){
// a = Id of parent element
// b = Class Name of element which you want to hack
var soldItems = document.getElementById(a).getElementsByClassName(b);
for(var i=0; i<soldItems.length; i++){
soldItems[i].innerHTML = "Coming Soon"
}
}
myF("thumb-hockey-top", "product-mark sold-out");
myF("thumb-hockey-bottom", "product-unmark sold-out");
<div class="example1">
<div id="thumb-hockey-top">
<div class="product-mark sold-out">EXAMPLE 1</div>
</div>
<div class="product-mark sold-out">EXAMPLE 1</div>
</div>
<div class="example2">
<div id="thumb-hockey-bottom">
<div class="product-unmark sold-out">EXAMPLE 2</div>
</div>
<div class="product-unmark sold-out">EXAMPLE 2</div>
</div>
You can get the parent element of an element using the parentElement attribute. Then just check its id.
var soldItem = soldItems[i];
if (soldItem.parentElement.id == "thumb-hockey-top") {
// do your thing
}

Categories

Resources