moving an element in JS - javascript

I'm learning javascript and trying to make a simple exercise : I have a text box and want control it with keyboard.
My HTML is the following (for now, I'm just trying 1 direction)
const myBox = document.querySelector("h1");
document.addEventListener('keydown', function (event){
if (event.keyCode == '38'){
myBox.style.top -= 5;
console.log("test if it works");
}
});
and my HTML is
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Tuto</title>
<style>
h1 {
width: 200px;
height: 40px;
border: 5px solid #BADA55;
color: #A28;
margin: 0;
text-align: center;
}
</style>
</head>
<body>
<div><h1>My text</h1></div>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
My check test with console log works. So event listener does.
But my box doesn't move. How can I solve it and why my use of .style.top is incorrect ?
Thank you

Positions property like "top", "bottom", "left" and "right" will not work unless your element has the property "position" as "absolute" or "relative".
In that case, what you want is to add "position: relative" to your h1 style on css.
If you want to understand more about that, this can give you a headstart https://www.w3schools.com/css/css_positioning.asp :D

To move an element by changing it's top value, the element can't have a static position (the default). You'll need to change the position to absolute, relative, fixed, etc....
Get the current top, left, etc... using Element#getBoundingClientRect, which will give you the correct initial value, and save you the need to parse a string. Since top needs to have a unit (px, em, etc..), add px to the changed top.
const myBox = document.querySelector("h1");
document.addEventListener('keydown', function(event) {
if (event.keyCode == '38') {
myBox.style.top = myBox.getBoundingClientRect().top - 5 + 'px'; // parse the string to number, subtract 5, and add 'px'
console.log(myBox.style.top);
}
});
h1 {
position: absolute;
top: 0;
left: 0;
width: 200px;
height: 40px;
border: 5px solid #BADA55;
color: #A28;
margin: 0;
text-align: center;
}
<div>
<h1>My text</h1>
</div>

1- you have to use let not const, because you want to change it and it is not fix;
let myBox = document.querySelector("h1");
2- you have to set your element as absolute position. because top property work not in static position
position:absolute;
3- you have to convert value of top position to number and then do something
myBox.style.top = parseFloat(myBox.style.top || 0) - 5 + 'px';
see my code : https://codepen.io/miladfm/pen/dRNLvw

Related

Make an element falling down to the page using html ,css, js

I want to make the grid element to fall down to the page . I used setInterval to repeat the proces (the bottom will decrease so the grid will descend ) . I think I didn't create move() function correctly.I just want to know how can I set the function correctly .
!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>
<link rel= "stylesheet" href ="style.css"></link>
</head>
<body>
<div class="grid"></div>
<script src="javascript.js" ></script>
</body>
</html>
.grid {
background-color:blue;
height: 20px;
width :100px;
left:600px;
top:150px;
position : absolute;
}
var grid =document.querySelector('.grid');
function move () {
grid.style.bottom-=4;
grid.style.bottom=grid.bottom +'px';
}
move();
setInterval(move,30);
If you would still like to implement your approach to realize this movement, here is some feedback.
Bottom value is String, not numerical (e.g. 300px vs 300)
If you want to manipulate the bottom value of an element, you have to parse the numerical value first, then change it, and then append a 'px' (or whatever unit you're using).
// grid.style.bottom-=4; // subtraction on strings is not allowed
// instead, use:
const currentBottom = parseInt(grid.style.bottom, 10)
grid.style.bottom = (currentBottom - 4) + 'px'
document.getElementById(...).style misses styles from <style> blocks and stylesheets
If you want to get all current styles of a DOM element, you should use window.getComputedStyle. As described in the docs:
getComputedStyle is read-only, and should be used to inspect the element's style — including those set by a element or an external stylesheet
In the snippet below, you can see and compare the values grid.style.bottom and window.getComputedStyle(grid). At first, the first version is empty, but the second has the expected value from the stylesheet.
Alternatively, you could directly apply the style in-line with the HTML element. Then you could use .style as well for accessing the correct value from the beginning.
<div class="grid" style="bottom: 100px"></div>
Check out the fixed version of the snippet below with a delay of 3 seconds for better understanding.
var grid = document.querySelector('.grid');
function move() {
const style = grid.style.bottom
const computedStyle = window.getComputedStyle(grid)
console.log('bottom', style)
console.log('bottom from computed style', computedStyle.bottom)
// grid.style.bottom -= 4;
// grid.style.bottom = grid.bottom + 'px';
const newBottom = parseInt(computedStyle.bottom, 10) - 4; // parseInt only reads the numeric value from the bottom string
grid.style.bottom = newBottom + 'px';
}
move();
setInterval(move, 3000);
.grid {
background-color: blue;
height: 20px;
width: 100px;
left: 100px;
bottom: 200px;
position: absolute;
}
<div class="grid"></div>
I would recommend you to use a CSS animation for that, you don't need JavaScript for that.
.grid {
background-color: blue;
height: 20px;
width: 100px;
left: 100px;
position: absolute;
animation: move 1.5s forwards;
}
#keyframes move {
from {
bottom: 200px;
}
to {
bottom: 0;
}
}
<body>
<div class="grid"></div>
</body>

How to increment top attribute of div in JS? [duplicate]

This question already has answers here:
How to retrieve the display property of a DOM element?
(4 answers)
Closed 3 years ago.
i need to increment the value top attribute of a div. for some reason it doesn't work.
i tried to use obj.style.top and increase the value but it doesn't work.
let sqr = document.getElementById("sqr")
let val = parseInt(sqr.style.top)
sqr.style.top = (val + 100) + "px";
body {
width: 100vw;
height: 100vh;
position: relative;
}
#sqr {
height: 30px;
width: 30px;
background-color: blue;
position: absolute;
top: 100px;
left: 100px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Document</title>
<link rel="stylesheet" href="index2.css" />
</head>
<body>
<div id="sqr"></div>
<script src="index2.js"></script>
</body>
</html>
I just want the square move up about 100 px.
thanks.
Use
sqr.style.top= (sqr.offsetTop + 100) + "px";
style.top returns the top value set in style attribute on the html tag.
The .style DOM property returns a CSS Style Declaration object containing the styles that have been set on the object through the HTML style attribute. Since your div doesn't have any inline styles applied to it, that technique won't return anything.
Instead, use getComputedStyle(), which returns the computed value of any/all styles, regardless of how/where they were set (inline, JavaScript, stylesheet).
Also (FYI):
As a best practice, you should always specify the optional second argument for parseInt() (the radix) to ensure you don't accidentally get a value you didn't expect.
let sqr = document.getElementById("sqr")
let val = parseInt(getComputedStyle(sqr).top, 10);
sqr.style.top= (val + 100) + "px";
body{
width:100vw;
height:100vh;
position: relative;
}
#sqr{
height: 30px;
width:30px;
background-color: blue;
position:absolute;
top:100px;
left:100px;
}
<div id = "sqr"></div>

javascript: change CSS position by relative amount

Basically what I'm trying to do is every time the JavaScript is executed (by click), the CSS left value for my <div> descreases by 20%. So, for example, left starts at 40%. The first time you click it should become 20%, and then 0%, and then -20%, and so on. I've updated my code below:
FilmstripLeft = parseInt(document.defaultView.getComputedStyle(ul).left, 10) / 4;
ul.style.left = (FilmstripLeft - 20) + "%";
ul is a <div> I get using document.getElementById(). This code works now, but I'm unsure about the divided by 4 at the end of the first line. I tested than that line was returning a value of 160 before I added the / 4 at the end, even though the starting value is 40%. I'm not sure if this is because it's returning the value in pixels instead of percent, in which case dividing by 4 would only work if left is at 160px?
"left" value for my div descreases by 20%
No. According to your explanation, you want to decrease it by 20 percentage points, not by 20%.
getComputedStyle(ul).left
Be aware percentages are relative units. When computed, they are transformed to an absolute length.
You can only access the raw percentage as an inline style
var target = document.getElementById("target");
document.querySelector('input').addEventListener('click', function() {
target.style.left = parseFloat(target.style.left) - 20 + '%';
});
#target {
position: relative;
width: 30px;
height: 30px;
background: blue;
}
<div id="target" style="left: 80%"></div>
<input type="button" value="Click" />
But you don't need the raw percentage in order to subtract 20 percentage points. You can use calc:
var target = document.getElementById("target");
document.querySelector('input').addEventListener('click', function() {
var current = getComputedStyle(target).left;
target.style.left = 'calc(' + current + ' - 20%)';
});
#target {
position: relative;
left: 80%;
width: 30px;
height: 30px;
background: blue;
}
<div id="target"></div>
<input type="button" value="Click" />
getComputedStyle() won't work well for your purposes because it, by definition, returns the computed value of the style in terms of pixels, not the relative percentage of the original value. In order to calculate what "20%" is using computed styles, you will have to do it manually by finding the parent element's width and then taking 20% of that:
function onClick(){
var myElement = document.getElementById("inner");
var leftValue = parseFloat(window.getComputedStyle(myElement).left);
var parentElement = myElement.parentElement;
var parentWidth = parseFloat(window.getComputedStyle(parentElement).width);
var twentyPercent = parentWidth * 0.20;
var newLeftValue = (leftValue - twentyPercent) + "px";
myElement.style.left = newLeftValue;
updateStatus();
}
function updateStatus(){
document.getElementById("status").innerHTML = window.getComputedStyle(document.getElementById("inner")).left;
}
updateStatus();
document.getElementById("btn").addEventListener("click", onClick);
#outer {
width: 400px;
height: 20px;
background: #888;
}
#inner {
width: 20px;
height: 20px;
position: relative;
left: 80%;
background: red;
}
<div id="outer">
<div id="inner"></div>
</div>
<button id="btn">click me</button>
<div id="status"></div>
The downside of this method is that it fixes left as a pixel value instead of a true percentage of the parent, so if the window/parent width changes, the left value won't match properly.
It's easier if the left value is an inline HTML style instead of a CSS style because you can get it directly with element.style, which reads the inline HTML style value. Then you can assign a new left value as a true percentage that will update if the window/parent width changes.
function onClick(){
var myElement = document.getElementById("inner");
// Note how #inner's left value is now inline instead of CSS
var leftValue = parseFloat(myElement.style.left);
var newLeftValue = (leftValue - 20) + "%";
myElement.style.left = newLeftValue;
updateStatus();
}
function updateStatus(){
document.getElementById("status").innerHTML = document.getElementById("inner").style.left;
}
updateStatus();
document.getElementById("btn").addEventListener("click", onClick);
#outer {
width: 400px;
height: 20px;
background: #888;
}
#inner {
width: 20px;
height: 20px;
position: relative;
background: red;
}
<div id="outer">
<div id="inner" style="left: 80%"></div>
</div>
<button id="btn">click me</button>
<div id="status"></div>
So, if possible, put your styles inline instead of into CSS because they're easier to access. Technically it is possible to access CSS stylesheet rules using JavaScript but it is very convoluted and I don't recommend it if you're new to web development.

change height of div by clicking it

I want to change the height of the div by clicking it.
Why it doesn't work at the first clicking but the second?
I don't know why, but the height of the div is "" (in the second clicking is 20px because of the else condition)
If I define the height of the div in the html element (style="height: 20px"), it works.
<html>
<head>
<script>
function divOpen() {
var divHeight= document.getElementById("divBottom").style.height;
if (divHeight=="20px") {
document.getElementById("divBottom").style.height="200px";
}
else {
document.getElementById("divBottom").style.height="20px";
}
}
</script>
<style>
div{
border:solid 1px gray;
width:200px;
height:20px;
}
.divBottom {
position: fixed;
bottom: 0;
right: 20px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="divBottom" id="divBottom" onclick="divOpen()"></div>
</body>
</html>
so I know how to fix it, but I don't know why the height is empty in the first clicking.
Please let me know..
any help appreciated!
In the initial click the height style property of your div is '' because you haven't set it.
There is a difference between setting height through the style property and by using a class. Try to refactor your code and make it use offsetHeight instead of style.height.
JavaScript
function divOpen() {
var divHeight= document.getElementById("divBottom").offsetHeight;
console.log(divHeight);
//22 because of the border
if (divHeight == 22) {
document.getElementById("divBottom").style.height="200px";
}
else {
document.getElementById("divBottom").style.height="20px";
}
}
DEMO

JavaScript and CSS positioning an image for any resolution

I am trying to create a simple slide show of an image that is set up in and background div. I dont have problem with creating the slideshow code but i have problem with positioning the image that should change according to the the width of others monitors resolution.
In the image bellow i described were i want to place the image. The image should be placed in the red div.
Here is the image that i want to put in the red div to be like a background. The resolution is (1900px x 500px)
Here is a model what i managed to do. I tried in java script code to declared a global variable sw which I assigned the window.innerWidth (sw=window.innerWidth), after in CSS using jquery selecting the red div $('#rotator') and assigned the sw ($('#rotator').css('width', sw)), but the result wasn't what I need to obtain. I obtained the image that was cropped from the right according to the screen resolution.
If someone know how to solve this question i will be greatful!
Here is my CODES:
HTML
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="jquery-2.1.0.js"></script>
<script type="text/javascript" src="function.js"></script>
<script src="jquery.easing.1.3.js"></script>
</head>
<body >
<div id="rotator"></div>
<div class='slider'></div>
</body>
</html>
CSS
body{
margin: 0px;
margin-left: 0px;
}
.slider{
width: 940px;
height: 360px;
background-color: #FFDF00;
margin: 0 auto;
position: absolute;
left: 15%;
top: 20px;
}
#rotator {
position: relative;
height: 500px;
}
.puzzle {
width: 100px;
height: 100px;
background-position: -100px 0px;
float: left;
}
And JavaScript that also contain the function of slideshow effect (that is working).
$(document).ready(init)
sw=window.innerWidth;
if (sw % 100 == 0) {
sw=window.innerWidth
}
else{
sw=Math.floor(sw/100)*100
}
//counter of slider
current_slide=0;
image_list=new Array
(
"img/1.jpg",
"img/2.jpg",
"img/3.jpg",
"img/4.jpg",
"img/5.jpg"
);
function init ()
{
$('#rotator').css('width', sw)
change(image_list[current_slide]);
//start timer
setInterval( "change(image_list[current_slide])" ,2500);
}
function change(bg_image){
// this function creats cells inside <div id = 'rotator'>
rot = $('#rotator'); //constructor
rot.empty();
for(y = 1; y<=5; y++)
{
for(x = 1; x<=sw/100; x++)
{
rot.append('<div class = "puzzle p-' + x + '-' + y + ' "></div>');
//select the <div> using his class and setting up the cells coordinates
$('.p-' + x + '-' + y).css('background-position', (-(x-1)*100) + 'px ' + (- (y-1)*100) + 'px').css('background-image','url('+bg_image+')');
$('.p-' + x + '-' + y).css('opacity', 0).delay(parseInt(Math.random()*1000)).animate({opacity: 1}, {duration: 1000})
}
}
current_slide++;
if(current_slide >= image_list.length)current_slide=0
}
Thank you for your time and consideration!
You either have to put the image into a container div who's width is dynamic to the size of the page and set width of the image inside it to 100%, or use the CSS attribute background-size: cover; (which is only compatible with newer browsers).
Images set as the background image for a div will simply fill their container and be clipped by that container as it shrinks past the dimensions of the background image unless background-size: cover; is used. To gain the same effect in older browsers, the aforementioned 100% trick is used.
Cross-browser style:
http://jsfiddle.net/2D5Vw/
New(ish)-School:
http://jsfiddle.net/HLf2Q/

Categories