I'm attempting to add a child span to all div's with the same class.
I can achieve this to a individual element by targeting its Id
HTML
<div id="h1" class="header">Hello </div>
<hr>
<div id="h2" class="header">what about this one </div>
JavaScript
var header = document.getElementById('h1');
var newSpan = document.createElement("span");
header.appendChild(newSpan);
newSpan.innerHTML = "i'm here";
However when I change it to
var header = document.getElementsByClassName('header');
It fails to work.
Can anyone see where I'm going wrong?
JSFiddle
To do that you need to iterate over them, since getElementsByClassName() returns an array like html element collection. You can use for loop
var headers = document.getElementsByClassName('header');
for (var i = 0; i < headers.length; i++) {
var newSpan = document.createElement("span");
newSpan.innerHTML = "i'm here";
headers[i].appendChild(newSpan);
}
<div id="h1" class="header">Hello</div>
<hr>
<div id="h2" class="header">what about this one</div>
or you can use Array.prototype.forEach with call() to iterate over it
var headers = document.getElementsByClassName('header');
[].forEach.call(headers,function(ele) {
var newSpan = document.createElement("span");
newSpan.innerHTML = "i'm here";
ele.appendChild(newSpan);
})
<div id="h1" class="header">Hello</div>
<hr>
<div id="h2" class="header">what about this one</div>
For more about iteration check :- For loop for HTMLCollection elements
The javascript document.getElementById will return only one Id, but document.getElementByClassName will return a collection of array-like objects and it should be used here.
I have updated your js code to :
var header = document.getElementsByClassName('header');
//console.log(header);
for(var i=0;i<header.length;i++){
var newSpan = document.createElement("span");
header[i].appendChild(newSpan);
newSpan.innerHTML = "i'm here";
}
and HTML code to :
<div id="h1" class="header">Hello </div>
<hr>
<div id="h2" class="header">what about this one </div>
HTML code had some slight mistake of class"header" instead class="header"
Fiddle
You can consider inserting the text as CSS generated content:
.header::after {
content: "i'm here";
}
<div id="h1" class="header">Hello </div>
<hr />
<div id="h2" class="header">what about this one </div>
Related
I am trying to create an element in JavaScript and apply it to all elements by class name. For this example I will use a paragraph for ease. The purpose of creating an element by JavaScript however is because I want to create a different element later on in my code.
In the code I am using, only the last element of the array of elements will contain the element created by the JavaScript. Could anyone explain why this is happening and what I could do to solve the problem accordingly to my requirement? I am trying to apply a whole element inside another element (so not just a value or property of a paragraph element).
My code:
//Creating my element:
let myElement = document.createElement("p");
/*let text = document.createTextNode("test");
myElement.appendChild(text);*/ //<-- Enable following to see text in result or check developer console for added paragraphs
//Single example:
let ele = document.getElementById("bar");
ele.appendChild(myElement);
//Not working...:
//Now class:
let eles = document.getElementsByClassName("foo");
for (i = 0; i < eles.length; i++) {
//eles[i].innerHTML = "abc";//<-- Does work (but hardcoded)?
//eles[i].innerHTML = myElement;//<-- returns "[object HTMLParagraphElement]"?
eles[i].appendChild(myElement); //<!-- Does work only for last element in array?
}
<div class="foo" id="bar">
</div>
<div class="foo">
</div>
<div class="foo">
</div>
<div class="foo">
<!-- Only this one will obtain the the paragraph element? -->
</div>
JSFiddle
You need to use cloneNode of element <p>, because appendChild moves it from its current position to the new position. See documentation
//Creating my element:
const myElement = document.createElement("p");
myElement.innerHTML = 'paragraph';
//Single example:
const ele = document.getElementById("bar");
ele.appendChild(myElement.cloneNode(true));
//Now class:
const eles = document.getElementsByClassName("foo");
for (let i = 0; i < eles.length; i++) {
eles[i].appendChild(myElement.cloneNode(true));
}
.foo {
border: 1px solid #333;
}
.foo p {
font-weight: bold;
}
<div class="foo" id="bar">
bar:
</div>
<div class="foo">
foo1
</div>
<div class="foo">
foo2
</div>
<div class="foo">
foo3
</div>
Your <p> element is appended only to the last because it is assigned to the myElementvariable. And because that variable is declared before your loop, each iteration will move the <p> tag through all your <div.foo>.
But if you declare your paragraph inside your for loop, a new one is created and appended to each of your blocks, because there are all different elements.
let eles = document.getElementsByClassName("foo");
for (i = 0; i < eles.length; i++) {
let myElement = document.createElement("p");
myElement.innerText = 'I am a paragraph.';
eles[i].appendChild(myElement);
}
<div class="foo" id="bar">
</div>
<div class="foo">
</div>
<div class="foo">
</div>
<div class="foo">
</div>
I'm trying to loop through divs and set the content of a div inside the outer div. I tried this.
Here is the HTML div's I want to loop through and I want to set the content of div with class content-detail with the value for its attribute data-form data.
//the javascript code I used is this
$(function($) {
for (var i of $(".item .content-detail")) {
var container = document.querySelector($(i)[0]);
var formData = $(i).attr("data-formdata");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<div class="item">
<div class="down-div"> </div>
<div class="detail">
<h4>Detail</h4>
<div id="div_" class="content-detail" data-formdata="my Item">
</div>
<div class="text-center">
<button class="btn btn-blue center"> SET !</button>
</div>
</div>
</div>
<div class="item">
<div class="down-div"> </div>
<div class="detail">
<h4>Detail</h4>
<div id="div_" class="content-detail" data-formdata="my Item">
</div>
<div class="text-center">
<button class="btn btn-blue center"> SET !</button>
</div>
</div>
</div>
But am stuck at this point var container = document.querySelector($(i)[0]);
I don't know how to get the jquery selector of that current div to a variable.
This may need some tweaks, but it should be close...
$(function ($) {
$(".item .content-detail").each(function(index, element) {
element.text($(element).attr("data-formdata"))
})
});
Take a look at the .each() method
$(function($) {
for (var i of $(".item .content-detail")) {
//var container = document.querySelector($(i)[0]);
var container = i;
var formData = $(i).attr("data-formdata");
}
});
I just needed the element
If you want to set the content of each DIV, you don't need a for loop. The .text() method takes a callback function, and it will be called on each element that matches the selector. The returned value is used as the new content.
$(".item .content-detail").text(function() {
return $(this).data("formdata");
});
This works.
$(function($) {
$(".item .content-detail").text(function(){
return $(this).attr("data-formdata");
})
});
Can you not just use JS like this:
[UPDATED]
function test() {
var divs = document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
var divsSub = divs[i].getElementById("div_").querySelectorAll(".content-detail");;
for (var iS = 0; iS < divsSub.length; iS++) {
var x = divsSub[iS].getAttribute("data-formdata");
divsSub[iS].innerHTML = x;
}
}
}
I am using wordpress and I want to add some html code on page using Javascript. I don't want to make child theme then edit php files. It is risky and I don't know about php.
I want to add a sibling div. This is an example code as default.
<div class="div1">
<div class="div1inside">
Text
</div>
</div>
<div class="div2">
<div class="div2inside">
Text
</div>
</div>
Now I want to add my custom div and its inside html between both div1 and div2.
<div class="mydiv">
<div class="mydivinside">
Text
</div>
</div>
Please let me know how is it possible using Javascript.
There are (at least) two ways, the first:
// document.querySelector() finds, and returns, the first element
// matching the supplied selector (or null, if no element is found):
var el1 = document.querySelector('.div1');
// here we create an adjacent element from the string of HTML,
// the 'afterend' argument states that this adjacent element
// follows the el1 node, rather than preceding it or appearing
// within:
el1.insertAdjacentHTML('afterend', '<div class="mydiv"><div class="mydivinside">Text</div></div>');
var div1 = document.querySelector('.div1');
div1.insertAdjacentHTML('afterend', '<div class="mydiv"><div class="mydivinside">Text</div></div>');
<div class="div1">
<div class="div1inside">
Text
</div>
</div>
<div class="div2">
<div class="div2inside">
Text
</div>
</div>
And the second where you first create that <div> to be inserted, and then use parentNode.insertBefore():
var htmlString = '<div class="mydiv "><div class="mydivinside">Text</div></div>',
// here we create a <div> element:
div = document.createElement('div'),
// we retrieve the element after which the new
// element should be inserted:
div1 = document.querySelector('.div1');
// assign the supplied HTML string to the innerHTML of the
// created element:
div.innerHTML = htmlString;
// and use parentNode.insertBefore to insert the desired element
// (the first argument) before the element identified in the
// second argument, which is the nextSibling of the found
// 'div1' element:
div1.parentNode.insertBefore(div.firstChild, div1.nextSibling);
var htmlString = '<div class="mydiv "><div class="mydivinside">Text</div></div>',
div = document.createElement('div'),
div1 = document.querySelector('.div1');
div.innerHTML = htmlString;
div1.parentNode.insertBefore(div.firstChild, div1.nextSibling);
<div class="div1">
<div class="div1inside">
Text
</div>
</div>
<div class="div2">
<div class="div2inside">
Text
</div>
</div>
References:
document.createElement().
document.querySelector().
Element.insertAdjacentHTML().
Node.firstChild.
Node.insertBefore().
Node.nextSibling.
Node.parentNode.
Use Node#insertBefore method.
// create a div element
var div = document.createElement('div');
// set class name
div.className = 'mydiv';
// set html contents
div.innerHTML = ' <div class="mydivinside"> Text </div>';
// get .div2 element
var ele = document.querySelector('.div2');
// insert before the .div2 element by getting
// its parent node
ele.parentNode.insertBefore(div, ele);
<div class="div1">
<div class="div1inside">
Text
</div>
</div>
<div class="div2">
<div class="div2inside">
Text
</div>
</div>
You can just use the before method to append a div between both div1 and div2. Here is the example:
$('.div2inside').before("<div class='mydiv'><div class='mydivinside'>Text</div></div>");
You could do something like this?
var firstDiv = document.getElementById('div1');
firstDiv.parentNode.insertBefore(document.getElementById('new-div'), firstDiv.nextSibling);
This however assumes that your new-div is already in the dom.
EDIT: to create a the new-div on the fly you can use #david-thomas's solution https://stackoverflow.com/a/41425079/1768337
This link will be helpfull to get the above result.
https://plainjs.com/javascript/manipulation/insert-an-element-after-or-before-another-32/
I have this HTML template on a page:
<div id="bid_wrapper_[[bid_id]]_[[template]]">
<div class="form_item_block" id="bid_wrapper_[[bid_id]]_[[template]]">
<div id="bid_delete_[[bid_id]]_[[template]]"><img src="/images/icons/cross.png"></div>
<div id="bid_label_wrapper_[[bid_id]]_[[template]]">Bid #1</div>
<div><input type="text" name="bid_summary" id="bid_summary_[[bid_id]]_[[template]]"></div>
<div><input name="bid_price" id="bid_price_[[bid_id]]_[[template]]"></div>
</div>
</div>
I'm trying to strip out the _[[template]] text, and also replace the [[bid_id]] with a number. I tried this:
var bid_template = document.getElementById('bid_wrapper_[[bid_id]]_[[template]]').cloneNode(true)
var new_bid_id = 2
var new_oh = bid_template.outerHTML
new_oh = new_oh.replace(/_\[\[template\]\]/g, '')
new_oh = new_oh.replace(/\[\[bid_id\]\]/g, new_bid_id)
At this point if I console.log new_oh, it is exactly what I want - everything is replaced correctly. However the next lines...
var new_bid = document.createElement('div')
new_bid.outerHTML = new_oh
Nothing happens here when I try to set the outerHTML. It does work if I set the innerHTML, but I would prefer to set the outerHTML. I don't get any error messages, and I can't figure out why it's not setting the outerHTML.
I assuming the error has occurred : that 'outerHTML' property on 'Element', so element has no parent node.
if you want to create it with new div, then :
var div = document.createElement('div');
div.innerHTML = output;
document.body.appendChild(div);
if not : then try this
var bid_template = document.getElementById('bid_wrapper_[[bid_id]]_[[template]]').cloneNode(true);
var new_bid_id = 2;
var parent = document.querySelector('.parent');
var new_oh = bid_template.outerHTML;
var output = new_oh.replace(/_\[\[template\]\]/g, '');
output = output.replace(/\[\[bid_id\]\]/g, new_bid_id);
parent.innerHTML = output;
alert(output)
<div class="parent">
<div id="bid_wrapper_[[bid_id]]_[[template]]">
<div class="form_item_block" id="bid_wrapper_[[bid_id]]_[[template]]">
<div id="bid_delete_[[bid_id]]_[[template]]">
<img src="/images/icons/cross.png">
</div>
<div id="bid_label_wrapper_[[bid_id]]_[[template]]">Bid #1</div>
<div>
<input type="text" name="bid_summary" id="bid_summary_[[bid_id]]_[[template]]">
</div>
<div>
<input name="bid_price" id="bid_price_[[bid_id]]_[[template]]">
</div>
</div>
</div>
</div>
You need to insert or append the new_bid div to the document first, then reset its outerHTML.
how can I delete with javascript html tag (for example span) but not the content and the html tags in the content?
one example:
<div id="content">
<span id=1 class="note" >
<p> <span id=1 class="note" >hello! its one example </span> </p>
<li> <span id=1 class="note" >yes,one example </span> </li>
</span>
</div>
the result should be:
<div id="content">
<p> hello! its one example</p><li>yes,one example</li>
</div>
Since you haven't mentioned that you need JQuery, following is the code that I propose:
http://jsfiddle.net/9qgK7/
Relevant code:
span.outerHTML = span.innerHTML;
Reference: https://developer.mozilla.org/en-US/docs/DOM/element.outerHTML
PS: Firefox only started supporting outerHTML since v11 but we are already using v15 :)
In your particular example, its probably best practice to just overwrite the immediate parentNode.
var content = document.getElementById('content'),
span = content.getElementsByTagName('span')[0],
p = content.getElementsByTagName('p')[0];
content.innerHTML = span.innerHTML;
Can easily be done with Jquery:
$('span.note').each(function(){
$(this).replaceWith($(this).html());
});
If you can use jQuery, try something like this
var newContent = $("#content span").html();
$("#content").html(newContent);
EDIT
Pure JS solution
var spans = document.getElementById("content").getElementsByClassName("note");
var out = "";
for (var i = spans.length - 1; i >= 0; i--) {
out += spans[i].innerHTML;
}
document.getElementById("content").innerHTML = out;
jsFiddle Example