Why is card element not duplicated 4 times?
function generate4Cards() {
for (var i=0; i < 4; i++) {
var card = document.getElementById('card');
document.body.appendChild(card);
}
}
<body onload="generate4Cards()">
<div id="card">I am a card</div>
</body>
When you call appendChild with an existing element, that element will be removed from its former position in the DOM and appended to the new container. You'll have to explicitly create the div on each iteration instead.
But, having duplicate IDs in a single document is invalid HTML, so probably best to remove the id (or use a class instead):
for (var i = 0; i < 4; i++) {
var card = document.createElement('div');
card.textContent = 'I am a card';
document.body.appendChild(card);
}
Another option is to use cloneNode:
var originalCard = document.querySelector('div');
for (var i = 0; i < 4; i++) {
var card = originalCard.cloneNode(true);
document.body.appendChild(card);
}
<div>I am a card</div>
foo.append(bar) puts bar at the end of foo.
If I put my car at the end of my road, and then put my car at the end of my drive then I don't have two cars.
append only puts bar where you tell it to put it.
It doesn't duplicate it because it isn't supposed to.
Here is the sample code you are looking for -
<html>
<head>
<script>
function generate4Cards() {
for (var i = 0; i < 4; i++) {
var card = document.createElement('div');
card.textContent = 'I am a card';
document.getElementById('cardHolder').appendChild(card);
}
}
</script>
</head>
<body onload="generate4Cards()>
<div id="cardHolder"></div>
</body>
</html>
Related
I have two loop like below you can see and need to add a custom active-numberHere class to the first image of each div with a specified number.
for example, if div class number is img-4 so add class active-4 to first img tag.
But I have some problems in code that you can see in the attached image.
in the first div image have the correct class.
but in other div image have extra active like active-4 active-3 and ...!
How can I solve this problem?
// LOOP Create Image Div
let numDiv = 5;
for (k = 0; k < numDiv; k++) {
//Add div area inside Div(products)
let imgPart = `<div class="img-${k} shoe-part"> </div>`;
document.querySelector(".products").insertAdjacentHTML("afterbegin", imgPart);
// LOOP Create Image List Inside Divs
let numImg = 3;
for (j = 0; j < numImg; j++) {
//Add Image List Inside Above Div(shoe-part)
let imgList = `<img class="res-img" src="img/image-${k}.png">`;
document.querySelector(".shoe-part").insertAdjacentHTML("afterbegin", imgList);
}
$('.shoe-part img:first-child').addClass(`active-${k}`);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="products">
</div>
Simple way to do this by jquery is to use html() and prepend() or append()
for add class you can use a simple if statement inside the loop
// LOOP Create Image Div
let numDiv = 5;
for (k = 0; k < numDiv; k++) {
//Add div area inside Div(products)
var DivPart = `<div class="img-${k} shoe-part"></div>`;
// LOOP Create Image List Inside Divs
let numImg = 3;
let ImgPart = '';
for (j = 0; j < numImg; j++) {
//Add Image List Inside Above Div(shoe-part)
var AddClass = (j === 0) ? 'active-'+k : ''; // shorthand if statement to add the class only when j = 0
ImgPart += `<img class="res-img ${AddClass}" src="img/image-${k}.png">`; // add all the images in the valriable ImgPart by using += it means sum/combine/addto
}
DivPart = $(DivPart).html(ImgPart); // update DivPart with the whole div with images in it
$('.products').prepend(DivPart); // prepend the DivPart to the product div
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="products">
</div>
I'm probably missing/doing something silly, but I can't seem to work this out:
Here's a fiddle showing the problem:
https://jsfiddle.net/jhqjmcn4/1/
Note that you will need to open your console to see what is happening.
Basically, in this example, I have two functions containing a for loop that are identical to each other except the second one contains a JQuery append.
The goal of the function is to get the html elements from within a string, which works fine in the first function, but not the second.
As can be seen in the console, this causes anything that is not a text node to be ignored and not added to the list. In this case, the b and p tags are not being included.
Here is the code again:
JS:
function parse_text(text) {
var div = document.createElement("DIV");
div.innerHTML = text;
var elements = div.childNodes;
var container = jQuery("#container");
var list = [];
for (var i = 0; i < elements.length; i++){
var element = elements[i];
list.push(element);
console.log("First", list);
}
}
function parse_text_two(text) {
var div = document.createElement("DIV");
div.innerHTML = text;
var elements = div.childNodes;
var container = jQuery("#container2");
var list = [];
for (var p = 0; p < elements.length; p++){
var element = elements[p];
list.push(element);
console.log("Second", list);
container.append(element);
}
}
var text = "Here is <b>some</b> text with <p>html</p> in it";
parse_text(text);
parse_text_two(text);
html (irrelevant):
<div id="container">
</div>
<div id="container2">
</div>
Thanks in advance.
I suppose you need to have a Array.prototype.filter() method to get the html elements:
function parse_text_two(text) {
var div = document.createElement("DIV");
div.innerHTML = text;
var elements = [].filter.call(div.childNodes, function(el) {
return el.nodeType !== 3;
});
var container = jQuery("#container2");
var list = [];
for (var p = 0; p < elements.length; p++) {
var element = elements[p];
list.push(element);
console.log("Second", list);
container.append(element);
}
}
var text = "Here is <b>some</b> text with <p>html</p> in it";
parse_text_two(text);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
</div>
<div id="container2">
</div>
You can check updated fiddle here jsfiddle.net/bharatsing/jhqjmcn4/3/
Its return same result for both methods in console as per you want.
function parse_text_two(text) {
var div = document.createElement("DIV");
div.innerHTML = text;
var elementsOrg = div.childNodes;
var elements = Array.prototype.slice.call(elementsOrg);;
var container = jQuery("#container2");
var list = [];
for (var p = 0; p < elements.length; p++){
var element = elements[p];
list.push(element);
console.log("Second", list);
container.append(element);
}
}
The issue I saw by putting a debug point inside the loop was this:
The container.append(element); statement was actually modifying the elements array and was removing the appended element from the array. Which meant that in the loop for various values of 'p' the elements array looked like this:
p = 0 -> elements : [ text, b, text, p, text ] // text node at 0 picked
p = 1 -> elements : [ b, text, p, text ] // text node at 1 picked
p = 2 -> elements : [ text, p, text ] // text node at 2 picked
That is why the loop only ran 3 times instead of the original length of the elements array , i.e. 5.
This probably happens because jQuery 'moves' the node from its original place to the container div.
You can either clone the element node and then append into the container:
function parse_text_two(text) {
var div = document.createElement("DIV"),
p,
element,
elements,
container = jQuery("#container2"),
list = [];
div.innerHTML = text;
elements = div.childNodes;
for (p = 0; p < elements.length; p++){
element = elements[p];
list.push(element);
console.log("Second", list);
container.append($(element).clone());
}
}
Or use a while loop as suggested in Venkatesh's answer. Anyway, it is always better to know the root cause. :)
Hope this helps.
In second function in each loop comment this line container.append(element);
I am programming a blackjack game and for each drawn card i create a tag <img> to display the card.
Naturally i have to delete this tag <img> after every game, but how can i do this?
Is there a way that I can remove all <img> tags within a parent?
Is there something like this: (Pseudecode)
div.removeAllChildElemtens()
or
div.removeChildElements("img");
Thanks.
If you create the elements using document.createElement('img') then you can keep a reference to them in order to delete them later.
var cards = [];
for (var i = 0; i < 52; i++)
{
var card = document.createElement('img');
// ... more initialisation of card
cards.push(card);
}
// later, to remove all
for (var i = 0; i < cards.length; i++)
{
var card = cards[i];
card.parentElement.removeChild(card);
}
Please, see the removeChild usage trick or use the new remove() function:
var div = document.getElementById("parentDivId");
var images = div.getElementsByTagName('img');
for(var i = 0; i < images.length; i++){
var img = images[i];
img.parentNode.removeChild(img);
//OR img.remove() as #Pete TNT pointed-out for modern web-browsers (FF/CH < 23)
}
I made a code that should highlight searched string but it is not working.
Here is the code:
<body>
<div>div is here</div>
<div id="divid">
<div>this is a div 1</div>
<div> this is a div 2</div>
<div> this is a div3</div>
</div>
<div> another div is here</div>
</body>
Here is a javascript code.
function checkit(){
var hlWord = "div";
var nregex = new RegExp(hlWord,"gi");
var div = document.getElementById("divid").getElementsByTagName('div');
for(var i=0; i <= div.length; i++){
var div1 = div[i].innerHTML;
var rword = div1.replace(nregex,"<b>"+hlWord+"</b>");
div1.innerHTML = rword;
}
}
There are begginer mistakes in your code. Let me correct them:
function checkit(){
var hlWord = "div"; //Define string that will be emphasized by <b> tag
var nregex = new RegExp(hlWord,"gi");//Create global, case-insensitive regexp
var div = document.getElementById("divid").getElementsByTagName('div'); //Get element collection of divs in div#divid
for(var i=0; i < div.length; i++){ //Loop through my element collection
var div1 = div[i].innerHTML; //Get the innerHTML of on of the divs
var rword = div1.replace(nregex,"<b>"+hlWord+"</b>"); //Surround my string with <b>
div[i].innerHTML = rword; //Change the innerHTML back
}
}
You used this for condition: i<=div.length. This is wrong. Do not forget, that we count from 0 so: [0, 1, 2, 3].length = 4. Last element for such array has index 3. The [] is an array literal.
By mistake, you assigned div1.innerHTML. div1 was a string. The element you want to change is div[i].
I made a JSFiddle too!
The problem with you code will be, amongst other problems, that nested div elements will be broken. You should use some kind of recursion if you want to highlight the word 'div'.
Here is such a function:
function highLight(term,root){
var allDiv = root.querySelectorAll('div'),
replacer = function(a){return '<span class="highlight">'+a+'</span>'};
for (var i=0; i<allDiv.length; i+=1){
if (allDiv[i].querySelectorAll('div').length){
highLight(term, allDiv[i]);
} else {
var re = RegExp('('+term+')','gi');
allDiv[i].innerHTML = allDiv[i].innerHTML.replace(re,replacer);
}
}
}
And here is a jsfiddle to play around with it
A more advanced jsfiddle
You have several errors: there you go:
http://jsfiddle.net/55U6j/1/
function checkit(){
var hlWord = "div";
var nregex = new RegExp(hlWord,"gi");
var divs = document.getElementById("divid").getElementsByTagName('div');
for(var i=0; i < divs.length; i++){
var div = divs[i];
var html = div.innerHTML;
var rword = html.replace(nregex,"<b>"+hlWord+"</b>");
div.innerHTML = rword;
}
}
How to get the position of last child in a element, I mean the number (the index)?
I want the code below to alert "4", since there is four elements.
<!DOCTYPE html>
<html>
<head>
<title>Untitled Document</title>
</head>
<body>
<div id="container">
<div id="div1">div1</div>
<div id="div2">div2
<div id="child_div1">div2</div>
<div id="child_div2">div2</div>
</div>
<div id="div3">div3</div>
<div id="div4">div4</div>
</div>
<script>
var container = document.getElementById('container'),
last_child_of_container = container.childNodes.length;
alert('position of last div is'+ last_child_of_container);
</script>
</body>
</html>
try
document.getElementById('container').children.length
http://jsfiddle.net/pxfunc/MGnCG/
This works :-)
var container = document.getElementById('container');
var count = 0;
var length = container.childNodes.length;
for (var i = 0; i < length; i++) {
if (container.childNodes[i].tagName &&
container.childNodes[i].tagName == 'DIV') {
count += 1;
}
}
alert(count);
Give document.getElementById('container').childElementCount a go
Here you go: http://jsfiddle.net/2t3VJ/
var container = document.getElementById('container'), children = 0;
for( var i=0, c = container.childNodes, l = c.length ; i < l; i++ ) {
if( c[i].nodeType == 1 ) { // if this is a HTMLSomeELement :)
children++;
}
}
alert( children );
Add h at the end of container.childNodes.lengt
container.childNodes.length;
See jsFiddle
For immediate child use childElementCount
container.childElementCount;
var container = window.document.getElementById("container");
var child_nodes = container.childNodes;
var child_nodes_length = child_nodes.length;
var count = 0;
var node;
var i;
for (i = 0; i < child_nodes_length; i++) {
node = child_nodes.item(i);
if (node.nodeType === 1) {
++count;
}
}
window.alert(count);
For people who wants any element (e.g. not necessarily the last one)
var wanted = document.getElementById('wanted');
var index = [].indexOf.call(wanted.parentElement.children, wanted);
Its very easy to get the position of the last element ... people are making it so complicated... try my code
function getLastElPos(container) {
return container.childNodes.length;
}
it returns the length of the child nodes in the container element, and the length means the last element (lol).
you can use it like this:
var container = document.getElementById('container');
var lastElement = getLastElPos( container );
alert( lastElement );
it works fine in all browser :)