Why the transform translate is not working? - javascript

I am using this code to simply move a small element(ball here), but the transform translate is only working once, even when the setInterval() function is continuously working?
This is the html file --
<!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="MoveTheBall.css">
<title>Move the ball</title>
</head>
<body>
<div class="ball"></div>
<script src="MoveTheBall.js"></script>
</body>
</html>
and CSS file--
.ball{
height: 5rem;
width: 5rem;
background-color: salmon;
border-radius: 50%;
position: relative;
top: 35vw;
left: 45vw;
}
and the JavaScript file--
var ball = document.querySelector('.ball');
document.addEventListener('keypress' , function(event) {
console.log('key', event.key);
if(event.key === 'w') {
moveUp();
}
});
function moveUp() {
let ballRect;
let interval = setInterval(function() {
ballRect = ball.getBoundingClientRect();
if(ballRect.top > 0) {
ball.style.transform = 'translateY(-10px)';
} else {
clearInterval(interval);
}
}, 300);
}
Here I was expecting to move the ball up until it reaches to the top of the screen after pressing w key. But the ball is only moving only once.

function moveUp() {
let ballRect;
let interval = setInterval(function() {
ballRect = ball.getBoundingClientRect();
if(ballRect.top > 0) {
let currentTop = parseFloat(getComputedStyle(ball).getPropertyValue('top'));
ball.style.transform = `translateY(${currentTop - 10}px)`;
} else {
clearInterval(interval);
}
}, 300);
}

Related

image slider with javascript with next previous button

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>

If and Else sentences, on first click

Hi I made this simple animation, when you click on the animate button, the function does not work the first time but it works the second time, how can it be? And what is the solution?
const fadeInOut = () => {
const divElement = document.getElementById('demo');
if (divElement.style.opacity == 0) {
divElement.style.opacity = 1;
} else {
divElement.style.opacity = 0;
}
};
#demo {
width: 300px;
height: 300px;
background: burlywood;
opacity: 1;
display: block;
transition: all 1s;
}
<!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>Document</title>
<script src="function.js" defer></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div id="demo"></div>
<button onclick="fadeInOut()">Animate</button>
</body>
</html>
It is because .style checks for an inline style, not the one you set in an external CSS file. You can go around this by setting an initial inline style to your element:
const fadeInOut = () => {
const divElement = document.getElementById('demo');
if (divElement.style.opacity == 0) {
divElement.style.opacity = 1;
} else {
divElement.style.opacity = 0;
}
};
#demo {
width: 300px;
height: 300px;
background: burlywood;
display: block;
transition: all 1s;
}
<div id="demo" style="opacity: 1"></div>
<button onclick="fadeInOut()">Animate</button>

Javascript "cannot read style property of null". Nothing is working [duplicate]

This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 1 year ago.
I have tried many other solutions on this problem but none of them are working. I checked my code from other questions I found and it seems to be perfectly fine.
I want the javascript to move the div called "snake" in what direction it is moving. But it keeps saying that snake is "null". Code:
Html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Snake</title>
<style>
#main {
height: 100px;
width: 100px;
border: 1px solid black;
}
#snake {
position: absolute;
top: 20px;
left: 20px;
width: 10px;
height: 10px;
background: black;
}
</style>
<script src="script.js"></script>
</head>
<body>
<div id="main">
<div id="snake"></div>
</div>
</body>
</html>
Javascript:
let movePos = null;
let isMoving = false;
let snake = document.getElementById("snake");
function main() {
document.addEventListener("keypress", function(event) {
if (event.key == "w") {
movePos = "up";
} else if (event.key == "s") {
movePos = "down";
} else if (event.key == "a") {
movePos = "left";
} else if (event.key == "d") {
movePos = "right";
}
if (!isMoving) {
askToMove();
}
});
}
function askToMove() {
if (movePos != null) {
isMoving = true;
setInterval(move, 1000);
}
}
function move() {
if (movePos == "up") {
snake.style.top = 100;
}
}
main();
You've made the javascript run before the "snake" element is defined. Just replace your current HTML code with this.
<!DOCTYPE html>
<html lang="en">
<body> <!-- Body shifted up -->
<div id="main">
<div id="snake"></div>
</div>
</body>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Snake</title>
<style>
#main {
height: 100px;
width: 100px;
border: 1px solid black;
}
#snake {
position: absolute;
top: 20px;
left: 20px;
width: 10px;
height: 10px;
background: black;
}
</style>
<script src="script.js"></script>
</head>
<!-- No Body Here -->
</html>
All I did was shift the body section up. I have had this same problem before and I fixed it with this.

CSS Absolute Positioning of Images

I was trying to position several images in a so they overlap with each other. I want to use absolute positioning, but for reason all of the images position themselves relative to the and not to each other. If I use s instead of images this works. It appears that, unlike s, images do not position themselves relative to other images but only to a , is that correct?
CSS
#container2 {
width: 340px;
height: 200px;
border: 1px solid black;
position: absolute;
top: 250px;
}
.playingcard {
width: 72px;
height: 100px;
position: absolute;
left: 0px;
}
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="styles.css">
<title>Document</title>
</head>
<body>
<div id=container2>
</div>
<script src=script.js></script>
</body>
</html>
JavaScript
const imageArray = ['/images/back/purple_back.png', '/images/back/red_back.png', '/images/back/yellow_back.png' ];
const container2 = document.getElementById('container2');
console.log(container2);
for (i = 0; i < imageArray.length; i++) {
const newImage = new Image();
newImage.src = imageArray[i];
newImage.className = 'playingcard';
imgArray = container2.getElementsByTagName('img');
console.log(imgArray.length);
if (imgArray.length == 0) {
container2.appendChild(newImage);
} else {
newImage.style.top = (i * 20) + 'px';
imgArray[imgArray.length - 1].appendChild(newImage);
}
}
Thanks
Denis
2 Observations
Your this code is never going to execute in a the for loop.
if (imgArray.length == 0) {
container2.appendChild(newImage);
}
You are pushing image in imageArray, so your structure will be like this
<container2>
<img src="src1">
<img src="src2">
<img src="src3">
</img>
</img>
</img>
</container2>
Here even if you use position absolute to each image will be absolute to its parent. so you will see overlapping images.
Replace your else condition with this (Remove if also)
else {
newImage.style.top = (i * 20) + 'px';
container2.appendChild(newImage); // ADD THIS
// imgArray[imgArray.length - 1].appendChild(newImage); // REMOVE THIS
}
Your structure now will be as you are expecting. You can play around with the CSS to get a view you want.
Your problem is that all img tags are nested within each other. Due to this, your top rule did not work. Example without condition if.
const imageArray = ['https://avatars.mds.yandex.net/get-pdb/2265897/d83bbab3-4bc4-42cc-8d62-a21b4c77ed72/s1200', 'https://64.img.avito.st/1280x960/4394790064.jpg', 'https://i.mycdn.me/i?r=AyH4iRPQ2q0otWIFepML2LxRUoA1zBVpY6nfGdB73g4vbw' ];
const container2 = document.getElementById('container2');
console.log(container2);
for (i=0; i<imageArray.length; i++) {
const newImage = new Image();
newImage.src = imageArray[i];
newImage.className = 'playingcard';
imgArray = container2.getElementsByTagName('img');
console.log(imgArray.length);
container2.appendChild(newImage);
newImage.style.top = (i * 20) + 'px';
}
#container2 {
width: 340px;
height: 200px;
border: 1px solid black;
position: absolute;
top: 250px;
}
.playingcard {
width: 72px;
height: 100px;
position: absolute;
left: 0px;
}
<!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="styles.css">
<title>Document</title>
</head>
<body>
<div id=container2>
</div>
<script src=script.js></script>
</body>
</html>

Show/hide div in viewport after 2 seconds

I want show when its in viewport after 2 seconds. And if its not in viewport just hide.
I watched a code, but its relative to other div and without delay.
Thx!
$(window).scroll(function() {
if ($('.waar').is(':in-viewport')) {
$('.sticky-info').hide();
} else {
$('.sticky-info').show();
}
});
You can refer this link - slideToggle w3school
slideToggle jquery api
Definition and Usage
The slideToggle() method toggles between slideUp() and slideDown() for the selected elements.
This method checks the selected elements for visibility. slideDown() is run if an element is hidden. slideUp() is run if an element is visible - This creates a toggle effect.
Syntax
$(selector).slideToggle(speed,easing,callback)
1. $(Your selectior).slideToggle("fast"); // fast
2. $(Your selectior).slideToggle("medium"); // meduim
3. $(Your selectior).slideToggle("slow"); // slow
Another example you can use this also
Please refer this link - > fadeToggle
$(function() {
$('#ButtonClick').on('click', function() {
$('#HideShowDiv').delay(1000).fadeToggle();
});
});
The below SO snippet might help!
<!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" />
<title>Document</title>
<style>
#container {
height: 1000px;
position: relative;
margin-top: 40px;
}
#inner {
width: 50%;
color: white;
margin: auto;
height: 50px;
background-color: green;
}
#sticky-info {
top: 0;
position: fixed;
z-index: 1;
display: block;
background-color: hotpink;
}
</style>
</head>
<body>
<div id="container">
<div id="inner">
Scroll me out of viewport
</div>
<div id="sticky-info">
Element in view
</div>
</div>
<script>
let inView = true;
let timeout = null;
window.addEventListener("scroll", () => {
const bounding = document
.getElementById("inner")
.getBoundingClientRect();
if (
bounding.top >= 0 &&
bounding.left >= 0 &&
bounding.right <= window.innerWidth &&
bounding.bottom <= window.innerHeight
) {
if (!inView) {
inView = true;
clearTimeout(timeout);
timeout = setTimeout(() => {
document.getElementById("sticky-info").style.display = "block";
}, 2000);
}
} else {
if (inView) {
clearTimeout(timeout);
inView = false;
timeout = setTimeout(() => {
document.getElementById("sticky-info").style.display = "none";
}, 2000);
}
}
});
</script>
</body>
</html>

Categories

Resources