How come my div is not printing for as many times as it loops?
I want the picture to be displayed 10 times and for some reason is is only showing up twice. Any ideas, all help is welcome and appreciated. Thanks!
I select the Div, I clone it, and now I want to display it 10 times.
var stuffIWantRepeated = document.getElementsByTagName("DIV")[0];
var clone = stuffIWantRepeated.cloneNode(true);
for (var i = 1; i <= 10; i++) {
document.body.appendChild(clone);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#maindiv img {
border-bottom-color: black;
display: block;
margin-left: auto;
margin-right: auto;
}
#maindiv {
padding-top: 10%;
}
</style>
</head>
<body>
<div id="maindiv">
<img src="https://pbs.twimg.com/profile_images/571024672750178304/GpGC8aTW.jpeg" border="40">
</div>
</body>
</html>
You have to clone once for each time you want to append it. A particular node can only be in the DOM in one place.
Just move that line into the loop:
for(var i = 1; i <= 10; i++) {
var clone = stuffIWantRepeated.cloneNode(true);
document.body.appendChild(clone);
}
!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#maindiv img {
border-bottom-color: black;
display: block;
margin-left: auto;
margin-right: auto;
}
#maindiv {
padding-top: 10%;
}
</style>
</head>
<body>
<div id="maindiv">
<img src="https://pbs.twimg.com/profile_images/571024672750178304/GpGC8aTW.jpeg" border="40">
</div>
</body>
<script>
var stuffIWantRepeated = document.getElementsByTagName("DIV")[0];
for (var i = 1; i <= 10; i++) {
var clone = stuffIWantRepeated.cloneNode(true);
document.body.appendChild(clone);
}
</script>
</html>
Rather than creating a clone and appending it ten times over, you should create ten clones and append each individually:
Replace:
<script>
var stuffIWantRepeated = document.getElementsByTagName("DIV")[0];
var clone = stuffIWantRepeated.cloneNode(true);
for(var i = 1; i <= 10; i++) {
document.body.appendChild(clone);
}
</script>
With this:
<script>
var stuffIWantRepeated = document.getElementsByTagName("DIV")[0];
for(var i = 1; i <= 10; i++) {
var clone = stuffIWantRepeated.cloneNode(true);
document.body.appendChild(clone);
}
</script>
For example: https://jsfiddle.net/40wukrta/
You need to clone it every time in your loop. Once appended into the document, the clone will get invalid.
var stuffIWantRepeated = document.querySelectorAll("DIV")[0];
for (var i = 1; i <= 10; i++) {
var clone = stuffIWantRepeated.cloneNode(true);
document.body.appendChild(clone);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#maindiv img {
border-bottom-color: black;
display: block;
margin-left: auto;
margin-right: auto;
}
#maindiv {
padding-top: 10%;
}
</style>
</head>
<body>
<div id="maindiv">
<img src="https://pbs.twimg.com/profile_images/571024672750178304/GpGC8aTW.jpeg" border="40">
</div>
</body>
</html>
Related
The general appearance of the program is as follows:
enter image description here
the details
In this exercise, we complete a simple slider. You must add the previous and next button in this event. The next or previous image should be displayed when the next or previous button is clicked. You can use the functions defined in the initial project.
When the slider is on the last image and the next button is clicked, the first image should be displayed and also when the first image of the previous button is clicked, the last image should be displayed.
Note: When an image is displayed, its opacity must be 1 and the rest of the images must be 0.
Notes
You are only allowed to make changes to the main.js file.
html code :
const sliderImages = [
"./images/image1.jpg",
"./images/image2.jpg",
"./images/image3.jpg",
"./images/image4.jpg",
];
const sliderDom = document.getElementById("slider");
let currentImage = 0;
function renderImages() {
sliderImages.forEach((image) => {
sliderDom.innerHTML += "<img src='" + image + "' />";
});
}
function clearImages() {
const images = document.getElementsByTagName("img");
for (let i = 0; i < images.length; i++) {
images[i].style.opacity = 0;
}
}
function showImage(image) {
clearImages();
document.getElementsByTagName("img")[image].style.opacity = 1;
}
function init() {
renderImages();
showImage(currentImage);
}
init();
let myBtn = document.querySelector("#prevButton");
myBtn.onclick = function() {
const newImage = (currentImage + 1) % sliderImages.length;
showImage(newImage);
}
let myBtn2 = document.querySelector("#nextButton");
myBtn2.onclick = function() {
const newImage = (currentImage + 1) % sliderImages.length;
showImage(newImage);
}
* {
margin: 0;
padding: 0;
}
button {
padding: 8px;
}
.container {
width: 500px;
margin: 20px auto;
}
#slider {
position: relative;
height: 400px;
margin-bottom: 20px;
}
#slider img {
width: 500px;
height: 400px;
position: absolute;
transition: all .5s;
}
.buttons {
display: flex;
justify-content: space-between;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Slider</title>
</head>
<body>
<div class="container">
<div id="slider"></div>
<div class="buttons">
<button id="prevButton"><</button>
<button id="nextButton">></button>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
var photos = ["images/img1.png", "images/img2.png", "images/img3.png", "images/img4.png"]
var imgTag = document.querySelector("img");
var count = 0;
function next(){
count++;
if(count >= photos.length){
count = 0;
imgTag.src = photos[count];
}else{
imgTag.src = photos[count];
}
}
function prev(){
count--;
if(count < 0){
count = photos.length -1;
imgTag.src = photos[count];
}else{
imgTag.src = photos[count];
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Slider</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<button onclick="prev()">prev</button>
<img src="images/img1.png" alt="" style="width:500px; height: 400px;">
<button onclick="next()">Next</button>
<script src="script.js"></script>
</body>
</html>
This question already has answers here:
Align inline-block DIVs to top of container element
(5 answers)
Vertical space between two inline-block and a block element
(5 answers)
Image inside div has extra space below the image
(10 answers)
Closed 1 year ago.
I am trying to create a 16x16 grid.
Everything works perfectly except that I have some space between my rows, I can't figure out why.
The spacing between the columns is perfect but the rows have some gap between them.
Here's my code:
const container = document.getElementById("drawingGrid");
let rows = document.getElementsByClassName("gridRow");
let cells = document.getElementsByClassName("cell");
function createGrid() {
makeRows(16);
makeColumns(16);
}
// create rows
function makeRows(rowNum) {
for (r = 0; r < rowNum; r++) {
let row = document.createElement("div");
container.appendChild(row).className = "gridRow";
}
}
// create columns
function makeColumns(cellNum) {
for (i = 0; i < rows.length; i++) {
for (j = 0; j < cellNum; j++) {
let newCell = document.createElement("div");
rows[j].appendChild(newCell).className = "cell";
}
}
}
createGrid();
.cell {
border: 1px solid gray;
min-width: 10px;
min-height: 10px;
display: inline-block;
margin: 0;
padding: 0;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>EtchASketch</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="drawingGrid">
</div>
<script src="app.js"></script>
</body>
</html>
And here's what it looks like on chrome:
You can turn the gridRow into a flexbox container. You can read the reason behind the space: Why does my image have space underneath? here.
const container = document.getElementById("drawingGrid");
let rows = document.getElementsByClassName("gridRow");
let cells = document.getElementsByClassName("cell");
function createGrid() {
makeRows(16);
makeColumns(16);
}
// create rows
function makeRows(rowNum) {
for (r = 0; r < rowNum; r++) {
let row = document.createElement("div");
container.appendChild(row).className = "gridRow";
}
}
// create columns
function makeColumns(cellNum) {
for (i = 0; i < rows.length; i++) {
for (j = 0; j < cellNum; j++) {
let newCell = document.createElement("div");
rows[j].appendChild(newCell).className = "cell";
}
}
}
createGrid();
.cell {
border: 1px solid gray;
min-width: 10px;
min-height: 10px;
display: inline-block;
margin: 0;
padding: 0;
}
.gridRow {
display: flex;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>EtchASketch</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="drawingGrid">
</div>
<script src="app.js"></script>
</body>
</html>
You should define the height of your row:
.gridRow{
max-height:10px;
}
or setting the line-height of your row:
.gridRow{
line-height:10px;
}
or using flexbox as defined by m4n0.
I would like to capture data from selected div(ie. name of country) by click and put in span , additionaly i want to find some way to mark selected divs, but also unmark others div which were selected previously.
https://codepen.io/tatasek/pen/PoojNGL
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<div class="div div__first"></div>
<div class="div div__second"></div>
<div class="div div__third"></div>
<p>I have selected:<span class="selectedCountry"></span></p>
<script src="app.js"></script>
</body>
</html>
CSS
body{
display: flex;
height: 100vh;
justify-content: center;
align-items: center;;
}
.div{
margin-left: 10px;
padding: 3px;
border: 2px solid black;
background-color: skyblue;
cursor: pointer;
}
p{
margin-left: 10px;;
}
.active{
background-color: yellow;
}
JS
const countries = ['Lithuania', 'Latvia', 'Estonia'];
const divList = document.querySelectorAll('.div');
divList.forEach(function(div, index){
div.textContent = countries[index];
})
Thanks for your time!
Michal
Building on what you've done so far, I just added some event listeners to check for changes and add the selected items to the list. Let me know if you need any further clarification.
const countries = ['Lithuania', 'Latvia', 'Estonia'];
const divList = document.querySelectorAll('.div');
divList.forEach(function(div, index){
div.textContent = countries[index];
div.addEventListener('click', function(){
divList.forEach(function(el, i) {
el.classList.remove('active')
})
this.classList.toggle('active');
})
})
var choices = document.getElementsByTagName('div')
for(var i = 0; i < choices.length; i++) {
choices[i].addEventListener('click', function() {
document.getElementsByClassName('selectedCountry')[0].innerText =
document.getElementsByClassName('active')[0].innerText;
})
}
body{
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
}
.div{
margin-left: 10px;
padding: 15px;
border: 2px solid black;
background-color: skyblue;
cursor: pointer;
}
p{
margin-left: 10px;
}
.active{
background-color: yellow;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<div class="div div__first"></div>
<div class="div div__second"></div>
<div class="div div__third"></div>
<p>I have selected:<span class="selectedCountry"></span></p>
<script src="app.js"></script>
</body>
</html>
Try
for (let i = 0; i < document.getElementsByClassName('div').length; i++) {
document.getElementsByClassName('div')[i].addEventListener('click', appendToSpan, false);
}
function appendToSpan(e) {
document.getElementsByClassName('selectedCountry')[0].innerText += e.target.innerText;
}
Edit:
Change to:
const countries = ['Lithuania', 'Latvia', 'Estonia'];
const divList = document.querySelectorAll('.div');
divList.forEach(function(div, index){
div.textContent = countries[index];
div.addEventListener('click', function() {
this.classList.toggle('active');
if (this.classList.contains('active')) {
document.getElementsByClassName('selectedCountry')[0].classList.add(this.innerText);
} else {
document.getElementsByClassName('selectedCountry')[0].classList.remove(this.innerText);
}
let classes = document.getElementsByClassName('selectedCountry')[0].getAttribute('class').split(' ');
document.getElementsByClassName('selectedCountry')[0].innerText = '';
for (let i = 1; i < classes.length; i++) {
document.getElementsByClassName('selectedCountry')[0].innerText += classes[i]
}
})
})
I've used addEventListener on click event on each div. Also I've created selected variable which is an array and keeps selected items. On click I check if the selected value is in selected variable by indexOf() function which returns -1 if there is not. Then I push() value to the array if it's not selected yet or delete it by splice() and index of value.
Array is printed by join() function which concats each value of array,
const divList = document.querySelectorAll('.div');
const output = document.querySelector('.selectedCountry');
const countries = ['Lithuania', 'Latvia', 'Estonia'];
let selected = [];
divList.forEach((div, index) => {
div.textContent = countries[index];
div.addEventListener('click',()=> {
var indexOfDiv = selected.indexOf(countries[index]);
(indexOfDiv >= 0)
? (selected.splice(indexOfDiv,1) && div.classList.remove('selected'))
: (selected.push(div.textContent) && div.classList.add('selected'))
output.textContent = selected.join(', ');
});
});
.div { border: 1px solid lightgray; margin: 0.5rem; padding: 0.25rem 0.4rem; }
.div.selected { border-color: lightgreen; }
<div class="div div__first"></div>
<div class="div div__second"></div>
<div class="div div__third"></div>
<p>I have selected:<span class="selectedCountry"></span></p>
const countries = ['Lithuania', 'Latvia', 'Estonia'];
const divList = document.querySelectorAll('.div');
const selectedCountry = document.getElementsByClassName('selectedCountry')[0];
function clearSelection() {
divList.forEach(function(div) {
div.classList.remove('active');
})
}
divList.forEach(function(div, index){
div.textContent = countries[index];
div.addEventListener('click', function() {
clearSelection();
this.classList.add('active');
selectedCountry.innerText = document.getElementsByClassName('active')[0].innerText;
})
})
body{
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
}
.div{
margin-left: 10px;
padding: 15px;
border: 2px solid black;
background-color: skyblue;
cursor: pointer;
}
p{
margin-left: 10px;
}
.active{
background-color: yellow;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<div class="div"></div>
<div class="div"></div>
<div class="div"></div>
<p>I have selected:<span class="selectedCountry"></span></p>
<script src="app.js"></script>
</body>
</html>
someone who use JS it could be very simple.
Need to overwrite styles of one class if page is loaded in Safari browser. I think I have it all, just this line of code is problem.
This command doesnt talk to all elements with same class but it should:
document.getElementsByClassName('.background').className += " safari";
This is what I have. Mistake is in that javascript function.
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
* {
margin: 0;
padding: 0;
}
div {
margin: 10px;
background: inherit;
width: 550px;
height: 450px;
}
.background {
background: rgba(255, 20, 0, 0.3);
filter: blur(10px);
}
.safari {
background: red!important;
-webkit-backdrop-filter: blur(10px)!important;
}
</style>
</head>
<body>
<div class='background'></div>
<div></div>
<div class='background'></div>
<div></div>
<div></div>
<script type="text/javascript">
if (navigator.userAgent.indexOf('Safari') != -1 &&
navigator.userAgent.indexOf('Chrome') == -1) {
document.getElementsByClassName('background').className += " safari";
}
</script>
</body>
</html>
WHAT I TRIED
1javascript
Have also tried using same code above changing class "background" to ID "background", than in javascript part of code i changed getElementsByClassName to getElementByID - that worked but it changed only first element with that ID. Rest of elements with that ID were ignored.
2conditional comment
I have tried avoiding JS and use conditional comment following link below - both browsers use webkit so I guess this is no way.
Is there any equivalent to IE conditional comment for chrome and safari?
Thanks for help.
You need to loop through all of the elements that have that class
var bgelements = document.getElementsByClassName('background');
for(var i = 0; i < bgelements.length; i++) {
bgelements[i].className += " safari";
}
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
*{
margin: 0;
padding: 0;
}
div{
margin: 10px;
background: inherit;
width: 550px;
height: 450px;
}
.background{
background: rgba(255,20,0,0.3);
filter: blur(10px);
}
.safari{
background: red!important;
-webkit-backdrop-filter: blur(10px)!important;
}
</style>
</head>
<body>
<div class='background'></div>
<div></div>
<div class='background'></div>
<div></div>
<div></div>
<script type="text/javascript">
if (navigator.userAgent.indexOf('Safari') != -1 &&
navigator.userAgent.indexOf('Chrome') == -1) {
var bgelements = document.getElementsByClassName('background');
for(var i = 0; i < bgelements.length; i++) {
bgelements[i].className += " safari";
}
}
</script>
</body>
</html>
I've got a sprite of two images, one position is 0 0, another 0 -150 px. I'd like to make them change every 10 seconds. I'm vaguely familiar with JavaScript, so far I've got
this:
function changeBackground () {
// some for loop? //
}
setInterval(function(){changeBackground()},10000);
I'm sorry this is realy just a few lines but I'm really lost. A little hint would be appreciated.
Something like this. This is untested, so there might be some errors, but you could solve it like this:
<div id="sprite"></div>
setBackgroundImage(frameNumber) {
var style = document.getElementById('sprite').style;
var pos;
if (frameNumber === 0) {
pos = 0;
} else if (frameNumber === 1) {
pos = -150;
}
style.backgroundPositionX = pos;
}
var currentFrame = 0;
function changeBackground () {
currentFrame ++;
currentFrame = currentFrame % 2;
setBackgroundImage
}
setInterval(function(){changeBackground()},10000);
Maybe this is help you if you need with animation please comment http://jsfiddle.net/hmZ7W/
var button = document.getElementById("button");
var oddEven = 1;
function changeBackground () {
if(oddEven)
{
button.style.backgroundPosition = "0 150px";
oddEven = 0;
}
else
{
button.style.backgroundPosition = "0 0";
oddEven = 1;
}
}
setInterval(function(){changeBackground()},500);
You may try this code for animation in JS:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style type="text/css">
#sprite {
width: 100px;
height: 100px;
background: url(image.jpg) 0 0;
}
</style>
</head>
<body onload="main();">
<script>
var pos = [-10, -20, -30]; // image offset
var posIdx = 0; // offset index
function main() {
var img = document.createElement('img')
img.id = 'sprite';
document.body.appendChild(img);
setInterval(function() {
anim(img);
}, 1000);
}
function anim(el) {
posIdx++;
if (posIdx > pos.length - 1) posIdx = 0;
el.style.backgroundPositionX = pos[posIdx] + 'px';
}
</script>
</body>
this is what i mean...
to support other browsers you need to add the other prefixes.(this works in chrome and safari)
NO javascript needed .. .especially NO timers.
your image is 'sprite.png' width 300px height 150px in this example
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
div{
width:150px;height:150px;
background:url(sprite.png) no-repeat 0px 0px;
-webkit-animation:mymove 10s infinite;
}
#-webkit-keyframes mymove{
0%{background-position:0px 0px;}
50%{background-position:0px 0px;}
51%{background-position:-150px 0px;}
100%{background-position:-150px 0px;}
}
</style>
</head>
<body>
<div></div>
</body>
</html>
another way to don't use the javascript timer... is to change class on transition end.
so 2 classes every transition lasts 10sec.. and on end it swaps class.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
div{
width:150px;height:150px;
background:url(sprite.png) no-repeat 0px 0px;
-webkit-transition:background-position 0s linear 10s;
}
div.odd{
background-position:-150px 0px;
}
</style>
</head>
<script>
window.onload=function(){
var div=document.getElementsByTagName('div')[0];
div.addEventListener('transitionend',function(){
this.classList.toggle('odd');
},false);
div.classList.toggle('odd');// start the transition
}
</script>
<body>
<div></div>
</body>
</html>