HTML5 and Javascript - a function appears to be working only once - javascript

guys, I am playing arround with HTML5 and javascript. The current thing which I am making is the following: there is a purple block on the screen and when you click a button it is moved 100 pixels to the right. This works so far, however, the function works only on the first time it is ran. I can't find my bug. I am posting the entire source code (javascript, html and css)
<!doctype html>
<head>
<style>
#stage{
position: relative;
width : 800px;
height : 600px;
background: #c0c0c0;
border: 1px dashed black;
}
.coil{
width: 64px;
height: 64px;
background: #800080;
position: absolute;
top: 200px;
left: 50px;
}
</style>
</head>
<body>
<div id="stage">
<div class="coil"></div>
<button id="button1">move!</button>
</body>
<script>
var coil = document.querySelector(".coil");
var button = document.querySelector("#button1");
button.addEventListener("click", clickHandler2, false);
//why is it working correctly just once
function clickHandler2()
{
coil.style.left += 100 + "px";
}
</script>

As nycynik mentioned, you are being a bit careless with the string additions.
Try this:
function clickHandler2()
{
var before = parseInt(coil.style.left);
before = isNaN(before) ? 0 : before;
coil.style.left = before + 100 + "px";
}

When you do your add like that, its not actually adding to the value, its only making a new string; add a console.log on the button and you will see.
console.log(coil.style.left += 100 + "px");
the output is "100px100px"
one alternative solution:
var coilPos = 100;
//why is it working correctly just once
function clickHandler2()
{
coilPos += 100;
coil.style.left = coilPos + "px";
console.log(coil.style.left += 100 + "px");
}

You must use a closure. A variable in the closure context must keep the left value. Then when applying the value to the property you use
var actualLeft += 100;
coil.style.left= actualLeft +"px";

Related

How do I increment the rotation property of this box one degree at a time?

I've wrote the following code in an attempt to rotate the box identified as "player" by one single degree to the left every time I strike the left arrow key on the key board. I tried setting the initial value of the degree by declaring a variable called "numberD" and setting it to 0. Then I incremented this variable with the numberD++; statement. Then I tried to attach the value from numberD into the statement following it by inserting it into the rotate degrees statement.
Im not getting any syntax errors however the box is not moving, i know the keystroke is working because i attached a console log to fire every time i strike the left key. i think my issue is that when i declare the numberD it doesn't know to connect it the the transform property of the CSS element player.
Any thoughts would be appreciated. Thx!
Also heres a CODEPEN LINK for this example.
<!DOCTYPE html>
<html>
<head>
<style>
body {
background-color: #1f1f2e;
margin: 0px;
padding: 0px;
}
#arena {
background-color:black;
margin: 0px;
padding: 0px;
width: 500px;
height: 500px;
}
#player {
background-color: white;
width: 10px;
height: 10px;
position: relative;
top:50%;
left:50%;
transform:rotate(0deg);
}
</style>
<script>
document.addEventListener("keydown", keyBoardInput);
function keyBoardInput() {
var i = event.keyCode;
if (i == 37) {
numberD = 0;
numberD ++;
document.getElementById('player').style.transform = "rotate(" +
numberD +"deg)";
console.log('fired');
}
}
</script>
<body>
<div id="arena">
<div id="player"></div>
</div>
</body>
</head>
</html>
Every time the function is called, you reset the value for the rotation: numberD = 0;
To fix this you have to declare the variable outside of the function. You could do this by defining it as a document wide variable: document.numberD = 0;
Here is the code:
document.addEventListener("keydown", keyBoardInput);
document.numberD = 0;
function keyBoardInput() {
var i = event.keyCode;
if (i == 37) {
document.numberD++;
document.getElementById('player').style.transform = "rotate(" + document.numberD + "deg)";
console.log('fired');
}
}
And here is a working example.

Exiting a for loop that creates divs when reached end of screen

I am trying to complete a little exercise that refreshes the page when the big button in the middle is clicked and the little dots change colour.
I have stopped the page from scrolling so the page is full of dots but I have noticed that the overflow property acts differently on different browsers. Then I thought of another issue, on mobile or tablets the dots will show differently again!
So I'm not sure if this is even possible but the desired result is for the loop to create dots until the screen is full and the button displaying in the middle of the screen.
Could someone please tell me if this idea is possible as I haven't been able to find any similar questions. Or if there is a better way to get my desired result. Also if you have the time could you please briefly explain why as I want to understand how it works and learn from it.
So...
This is the JavaScript
var htmlDot = "";
var red;
var green;
var blue;
var rgbColor;
function colourSelect() {
return Math.floor(Math.random() * 256 );
}
for(var i = 1; i<=100; i+=1) {
red = colourSelect();
green = colourSelect();
blue = colourSelect();
rgbColor = "rgb(" + red + "," + green + "," + blue + ")";
htmlDot += "<div style=\"background-color:"+ rgbColor + " \"></div>";
}
document.write(htmlDot);
This is the HTML
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="main.css">
</head>
<body>
<button id="refresh">Click Me!</button>
<script src="script.js"></script>
</body>
</html>
This is the CSS
body {
position: relative;
overflow: hidden;
}
#refresh {
font: 40px bold;
font-family: sans-serif;
width: 200px;
height: 200px;
display: inline-block;
border-radius: 50%;
margin: 5px;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
background-color: rgb();
}
div {
width: 50px;
height: 50px;
display: inline-block;
border-radius: 50%;
margin: 5px;
}
Thank you in advance
I think you're looking for something like this:
https://jsbin.com/racahapevi/edit?html,css,js,output
Key points:
Calculate numbers of dots that can fit horizontally
Calculate total numbers of dots
Define <html>, <body> width and height to 100% of the viewport
overflow: hidden on html, so there will not be scroll
Add onclick event the button.
Here some code:
var numDots = hdots * vdots;
while(numDots--){
red = colourSelect();
green = colourSelect();
blue = colourSelect();
rgbColor = "rgb(" + red + "," + green + "," + blue + ")";
htmlDot += "<div class='dot' style=\"background-color:"+ rgbColor + " \"></div>";
}
Instead of using 100 for the number of dots you have to figure out how many dots fit in your browser window given the dimensions of the browser window.
var w = window.innerWidth; // browser width
var h = window.innerHeight; // browser height
var size = 60; // 50px + 5px + 5px (width or height) + (left or top margin) + (right or bottom margin)
var hdots = Math.floor(w/size); // how many dots fit horizontally
var vdots = Math.floor(h/size); // how many dots fit vertically
var numDots = hdots * vdots;

Unable to animate DOM element in codepen

I want to simply animate a shape every x milliseconds. I'm doing this in CODEPEN.
I tried moving it using:
JavaScript:
ball.getBoundingClientRect().left += 100 + 'px'
ball.style.left += 100 + 'px'
jQuery:
$('#ball').position().left += 100 + 'px'
But nothing seemed to work. The ball appears, but does not move. The timeout is being called as well. No errors in console are being thrown.
var ball = null;
var ball_x = null;
var ball_y = null;
function doMove() {
ball.style.left += 100 + 'px';
setTimeout(doMove,100);
}
function init() {
ball = document.getElementById('ball');
ball_x = ball.getBoundingClientRect().left; //displays correct location
ball_y = ball.getBoundingClientRect().top; //displays correct location
doMove();
}
window.onload = init;
CSS:
#ball {
width: 25px;
height: 25px;
background-color: red;
border-radius: 50%;
position: absolute;
left: 100px;
top: 200px;
}
HTML:
<div>
<div id='ball'></div>
</div>
The problem is left css returns a text like 100px value not a numerical one so that won't work. So using += with it does a string concatenation not a numeric one creating a invalid value
getBoundingClientRect() returns a read-only object, so changing its properties don't have an effect
The returned value is a DOMRect object, which contains read-only left,
top, right and bottom properties describing the border-box in pixels.
top and left are relative to the top-left of the viewport.
var ball = null;
function doMove() {
ball.style.left = ((parseInt(ball.style.left) || 0) + 100) + 'px'
setTimeout(doMove, 2000);
}
function init() {
ball = document.getElementById('ball');
doMove();
}
window.onload = init;
#ball {
width: 25px;
height: 25px;
background-color: red;
border-radius: 50%;
position: absolute;
left: 100px;
top: 200px;
transition: left 2s;
}
<div>
<div id='ball'></div>
</div>

Incorrect jQuery element width calculation

Having a simple html code
<div id="header">
<div id="headerBox">
<div id="headerText">
</div>
</div>
</div>
with css styles
div#header {
display: block;
overflow: hidden;
margin: 0;
padding: 0;
width: 100%;
}
div#headerBox {
padding: 1em;
text-align: center;
white-space: nowrap;
border-bottom: 10px double gray;
}
div#headerText {
background: red;
display: inline-block;
}
and jQuery (2.x edge)
function resize(win) {
var size;
var w = $('#headerBox').width();
$('#headerText').html('');
$('#headerBox').css('font-size', 1 + 'px');
$('#headerText').html(
"width of <span style=\"font-size:2em;\">headerBox</span> element is " + w + "px");
while ($('#headerText').width() <= w) {
size = parseInt($('#headerBox').css('font-size').replace(/\D+$/, ''), 10);
$('#headerBox').css('font-size', (size + 1) + 'px');
}
$('#headerBox').css('font-size', size + 'px');
}
$(window).resize(function(e){
resize(this)
});
resize(window);
all together accessible via this fiddle,
I experience incorrect jQuery element width calculation. When you access the above fiddle, you see that headerText element is too wide. There should be same right padding as is on left side, text should be centered. Once you resize the Result window (in the fiddle), text is adjusted as supposed to.
Question is WHY there is incorrect calculation on the very first time?
It seems that var w = $('#headerBox').width(); is incorrect calculated. WHY?
Found the problem:
Due to padding: 1em; for headerBox, width of this element changes with change of font-size.
So in while loop I need to work with up-to-date information, not the one I stored at the beginning.
Therefore
var w = $('#headerBox').width();
...
while ($('#headerText').width() <= w) {
...
}
needs to be changed to
while ($('#headerText').width() <= $('#headerBox').width()) {
...
}
JQuery .width doesn't include the padding of #headerbox. Use .outerWidth to get correct width.
var w = $('#headerBox').outerWidth();

Check if a div touches another div

I've made margin of 2 divs move (using variable and variable++ or -- with style attribute in js to change margin) Like that:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<meta charset="utf-8" />
<title>Game</title>
<style>
body{
position: absolute;
background: #f00;
}
.point{
position: absolute;
width: 15px;
height: 15px;
background: #fff;
border-radius: 10px;
margin: 0px 0 0;
}
.player{
position: absolute;
text-align: center;
width: 200px;
height: 20px;
background: #0005ff;
margin: 550px 550px 0px;
}
</style>
<script>
var num = 550;
$(document).keydown(function (event) {
switch (event.keyCode) {
// Left Arrow
case 37: num = num-- - 15;
document.getElementById('player').style.margin = '550px ' + num + 'px 0px';
break;
// Right Arrow
case 39: num = 15 + num++;
document.getElementById('player').style.margin = '550px ' + num + 'px 0px';
break;
}
});
var nump = 0;
$(document).load(function () {
nump++;
document.getElementById('point').style.margin = nump + 'px 0px 0px';
});
</script>
</head>
<body>
<div class="point" id="point"></div>
<div class="player" id="player"></div>
</body>
</html>
Now I got problem about moving div named point.The div, point is not moving when I use $(document).load but the other div works. How can I fix that?
My second question is how can i check when div "point" touch div "player" then i'll return div point to the start and make a loop.
try this to move the point
var nump = 0;
var touch = false;
var flagtouch;
$(document).ready(function () {
flagtouch = setInterval(function(){
movePoint(nump);
},1000);
});
function movePoint()
{
document.getElementById('point').style.margin = nump + 'px 0px 0px';
touch = chekTouch(); // check whether the divs touches and return true if touched
if(touch)
{
clearInterval(flagtouch);
}
else
{
nump = nump+5;
}
}
For the second question:
With http://api.jquery.com/position/, you can known the position of both divs, and as you know too the width and height of the elements, you can calculate the region occupied by each element, and then when the elements touch each other.

Categories

Resources