So, I have an event listener keydown on arrow right, when you push the square moving on xPX but my parent element this w and h
set a 100px for example, and I would like to stop moving and I can't, I try with element.offsetWidth > 0 so them you can move.
Please look this fiddle : FIDDLE
Few errors in your code. I've commented fixes. Here is how i made it for the right arrow - you can apply same logic to the rest of the moves...
Code:
const carre = document.querySelector('.carre');
const main = document.querySelector('.main');
const w = main.offsetWidth - carre.offsetWidth; // this was wrong in your code
carre.style.left="0px"; // set start position
document.addEventListener('keyup', (event) => {
const positionLeft = parseInt(carre.style.left); //i've used style.left, rather, it gives expected numbers (10,20,30....)
if(event.keyCode == '39') {
if (positionLeft < w) { // this was fixed too
carre.style.left = (positionLeft) + 10 + 'px';
} else {
carre.style.left = '0'
}
}
})
DEmo:
const carre = document.querySelector('.carre');
const main = document.querySelector('.main');
const w = main.offsetWidth - carre.offsetWidth; // this was wrong in your code
carre.style.left="0px"; // set start position
document.addEventListener('keyup', (event) => {
const positionLeft = parseInt(carre.style.left); //i've used style.left, rather, it gives expected numbers (10,20,30....)
if(event.keyCode == '39') {
if (positionLeft < w) { // this was fixed too
carre.style.left = (positionLeft) + 10 + 'px';
} else {
carre.style.left = '0'
}
}
})
* {
box-sizing:border-box;
}
.carre {
position:absolute;
left: 0;
width: 50px;
height: 50px;
background-color: red;
}
.main {
position: relative;
width: 100px;
height: 100px;
border: 1px solid #000;
}
<main class="main">
<div class="carre"></div>
</main>
I rebuild your code:
document.addEventListener('keydown', (event) => {
const w = main.getBoundingClientRect().right - carre.getBoundingClientRect().right;
const positionLeft = carre.getBoundingClientRect().left;
if(event.keyCode == '39') {
if (w >= 0) {
carre.style.left = (positionLeft) + 10 + 'px';
} else {
carre.style.left = '0'
}
}
if (event.keyCode == '37') {
if (w >= 0) {
carre.style.left = (positionLeft) - 10 + 'px';
}else {
carre.style.left = '0'
}
}
})
Related
I am making an image slider/ carousel. If you drag it, the images will get momentum and will keep on moving for sometime. There are few issues, one of them is getting the following error frequently: "glide.js:104 Uncaught TypeError: Cannot read property '1' of undefined". JavaScript here is supposed to access a value that is inside an array, but since the array is empty, i'm getting this error. However, the array shouldn't be empty, as the code that empties the array, comes later. Project
var projectContainer = document.querySelector(".project-container")
var projects = document.querySelectorAll(".project")
// exProject is declared so that every project has same transalte to refer to instead of referring to their individual transalations
var exProject = projects[0]
var style = window.getComputedStyle(exProject)
exProject.currentTranslationX = (new WebKitCSSMatrix(style.webkitTransform)).m41
// after dragging, do not add force if mouse has not been moved for pauseTime milliseconds
pauseTime = 40
lastMousePositions = []
//this will set margin to 80, i thought this is better than hardcoding
elementAOffset = projects[0].offsetLeft;
elementBOffset = projects[1].offsetLeft;
elementAWidth = parseInt(getComputedStyle(projects[0]).width)
margin = (elementBOffset - (elementAOffset + elementAWidth))
//projects will teleport to other side if they hit either of the boundary
LeftSideBoundary = -(elementAWidth)
RightSideBoundary = (elementAWidth * (projects.length)) + (margin * (projects.length))
RightSidePosition = RightSideBoundary - elementAWidth;
//how often to update speed (in milliseconds)
intervalTime = 15
//how much speed is lost at every interTime milliseconds
frictionPerMilliseconds = (20 / 1000);
frictionPerMilliseconds *= intervalTime * 5;
mouseInitialPosition = 0;
mouseIsDown = false
startTime = 0;
speed = 0;
mousemoving = false
projectContainer.addEventListener("mousedown", e => {
mouseInitialPosition = e.clientX
mouseIsDown = true;
startDate = new Date();
startTime = startDate.getTime();
lastMousePositions.push(e.clientX)
speed = 0
})
projectContainer.addEventListener("mousemove", e => {
if (!mouseIsDown) return;
distanceTravelled = e.clientX - mouseInitialPosition
if (speed === 0) {
projects.forEach(project => {
project.style.transform = 'translateX(' + ((exProject.currentTranslationX) + ((distanceTravelled))) + 'px)';
shiftPosition(project, distanceTravelled)
})
}
if ((new Date()).getTime() - lastMousePositions[lastMousePositions.length - 1][1] > 50) {
lastMousePositions = []
}
pushToMousePositions(e.clientX)
})
projectContainer.addEventListener("mouseup", e => {
dragEnd(e);
})
projectContainer.addEventListener("mouseleave", e => {
dragEnd(e);
})
function dragEnd(e) {
finalPosition = e.clientX;
distanceTravelled = finalPosition - mouseInitialPosition
endDate = new Date();
endTime = endDate.getTime();
timeElapsed = (endTime - startTime) / 1000
mouseIsDown = false;
tempSpeed = distanceTravelled / timeElapsed
tempSpeed = (tempSpeed / 1000) * 15
if (tempSpeed < 0 && speed < 0) {
if (tempSpeed < speed) {
speed = tempSpeed
}
} else if (tempSpeed > 0 && speed > 0) {
if (tempSpeed > speed) {
speed = tempSpeed
}
} else {
speed = tempSpeed
}
if (lastMousePositions.length === 0) {
console.log("error gonna pop up")
}
if (endTime - (lastMousePositions[lastMousePositions.length - 1])[1] >= pauseTime) {
speed = 0
}
mouseExit(e)
intervalFunction = setInterval(move, intervalTime)
}
function mouseExit(e) {
mouseIsDown = false
lastMousePositions = []
var style = window.getComputedStyle(exProject)
exProject.currentTranslationX = (new WebKitCSSMatrix(style.webkitTransform)).m41
projects.forEach(project => {
project.style.transform = 'translateX(' + (exProject.currentTranslationX) + 'px)'
shiftPosition(project, 0)
})
}
function move() {
if (speed === 0) {
clearInterval(intervalFunction)
} else if (Math.abs(speed) <= frictionPerMilliseconds) {
style = window.getComputedStyle(exProject)
exProject.currentTranslationX = (new WebKitCSSMatrix(style.webkitTransform)).m41
projects.forEach(project => {
project.style.transform = 'translateX(' + ((exProject.currentTranslationX) + (speed)) + 'px)'
shiftPosition(project, 0)
})
speed = 0
} else {
style = window.getComputedStyle(exProject)
exProject.currentTranslationX = (new WebKitCSSMatrix(style.webkitTransform)).m41
projects.forEach(project => {
project.style.transform = 'translateX(' + ((exProject.currentTranslationX) + (speed)) + 'px)'
shiftPosition(project, 0)
})
speed < 0 ? speed += frictionPerMilliseconds : speed -= frictionPerMilliseconds;
}
}
function pushToMousePositions(positionToPush) {
if (lastMousePositions.length < 50) {
lastMousePositions.push([positionToPush, (new Date()).getTime()])
} else {
lastMousePositions.shift();
lastMousePositions.push([positionToPush, (new Date()).getTime()])
}
}
function shiftPosition(project, mouseMovement) {
//projectVisualPosition is relative to the left border of container div
projectVisualPosition = project.offsetLeft + (exProject.currentTranslationX + mouseMovement)
tempStyle = window.getComputedStyle(project)
if (projectVisualPosition < LeftSideBoundary) {
project.style.left = ((parseInt(tempStyle.left) + RightSidePosition + 350) + 'px')
}
if (projectVisualPosition > RightSidePosition) {
project.style.left = ((parseInt(tempStyle.left)) - (RightSidePosition + elementAWidth)) + 'px'
}
}
*,
*::before,
*::after {
margin: 0px;
padding: 0px;
box-sizing: border-box;
font-size: 0px;
user-select: none;
font-size: 0;
}
body {
position: relative;
}
.project-container {
font-size: 0px;
position: relative;
width: 1500px;
height: 400px;
background-color: rgb(15, 207, 224);
margin: auto;
margin-top: 60px;
white-space: nowrap;
overflow: hidden;
padding-left: 40px;
padding-right: 40px;
}
.project {
font-size: 100px;
margin: 40px;
display: inline-block;
height: 300px;
width: 350px;
background-color: red;
border: black 3px solid;
user-select: none;
position: relative;
}
<div class="project-container">
<div class="project">1</div>
<div class="project">2</div>
<div class="project">3</div>
<div class="project">4</div>
<div class="project">5</div>
<div class="project">6</div>
<div class="project">7</div>
<div class="project">8</div>
</div>
The problem is this:
projectContainer.addEventListener("mouseleave", (e) => {
dragEnd(e);
});
You're calling dragEnd(e) when the cursor leaves projectContainer. That can happen while the lastMousePositions array is still empty.
Option 1: Don't call dragEnd(e) on the mouseleave event
Option 2: Inside the dragEnd(e) function, check that the array is not empty before you try to access its elements:
if (lastMousePositions.length !== 0) {
if (
endTime - lastMousePositions[lastMousePositions.length - 1][1] >=
pauseTime
) {
speed = 0;
}
}
I'm attempting to create a classic "Snake game" using only vanilla Javascript. I got an issue with the snake movements when arrow keys are pressed. It didn't work as supposed to.
The entire code is look like this.
HTML
<div class="canvas" id="canvas">
<div class="snake" id="snake"></div>
<div class="food-item" id="food-item"></div>
</div>
CSS
.canvas {
position: relative;
width: 500px;
height: 500px;
background-color: rgba(203, 200, 200, 0.51);
}
.snake {
width: 18px;
height: 18px;
transform: translate(215px, 246px);
background-color: rgba(180, 9, 180, 0.808);
border-radius: 25px;
}
JS
//the position of element before movement
var pos = 0;
let ele = document.getElementById("snake");
//Add an event for button press
window.addEventListener("keydown", (key) => {
var keycode = key.key;
return {
keycode: keycode,
start: start(keycode),
};
});
//movement of the element
function start(key) {
let keys = key;
function automove() {
try {
if (pos === 380) {
clearInterval(movement);
} else if (keys === "ArrowRight") {
pos++;
ele.style.transform = "translate(" + pos + "px)";
} else if (keys === "ArrowLeft") {
pos++;
ele.style.transform = "translate(" + -pos + "px)";
} else if (keys === "ArrowUp") {
pos++;
ele.style.transform = "translateY(" + pos + "px)";
} else if (keys === "ArrowDown") {
pos++;
ele.style.transform = "translateY(" + -pos + "px)";
} else {
console.log("invalid command: " + Error);
}
} catch (error) {
console.log("Error: " + error);
}
}
const movement = setInterval(automove, 1000);
return movement;
}
the behavior of the code is this
What I'm doing wrong here... is there any alternative way of doing this ?
It would be great if you can support with a vanillaJs answer.
For a snake game, you want the character to move even when no key is pressed.
So you need to store the direction somehow.
here's an updated version:
https://jsfiddle.net/wmvqgku4/1/
JS:
var posX = 200;
var posY = 160;
var ele = document.getElementById("snake");
const UP =0;
const RIGHT =1;
const DOWN =2;
const LEFT =3;
var dir = 1;
window.addEventListener("keydown", (key) => {
keyhandler(key.key)
});
window.onload = function () {
ele = document.getElementById("snake");
ele.style.top = posY + "px";
ele.style.left = posX + "px";
setInterval( automove, 300);
console.log("Started.");
}
function keyhandler(keys) {
try {
if (posX >= 380) {
clearInterval(movement);
}
if (keys === "ArrowRight") {
dir = RIGHT;
} else if (keys === "ArrowLeft") {
dir = LEFT;
} else if (keys === "ArrowUp") {
dir = UP;
} else if (keys === "ArrowDown") {
dir = DOWN;
} else {
console.log("invalid command: " + keys);
}
} catch (error) {
console.log("Error: " + error);
}
}
function automove() {
switch ( dir ) {
case UP: posY--; break;
case DOWN: posY++; break;
case LEFT: posX--; break;
case RIGHT: posX++; break;
}
console.log(dir);
ele.style.top = posY + "px";
ele.style.left = posX + "px";
}
CSS:
.canvas {
position: relative;
width: 500px;
height: 500px;
background-color: rgba(203, 200, 200, 0.51);
}
.snake {
width: 18px;
height: 18px;
position: absolute;
background-color: rgba(180, 9, 180, 0.808);
border-radius: 25px;
}
I made the snake position absolute, and als kept track of the x/y position, so you can add checks for the bounds.
I also changed it a bit, the keyhandler checks the keys and updates the direction variable.
the automove now only checks the direction, and updates the position.
Hope this helps.
There are many "pull to refresh" plugins. I have already tested 5 of them. But none of them running fast (especially on old smartphones).
What is the best (buttery UX performance and responsiveness) way to check for pull to refresh?
PS: I don't need any animation. I just want to recognize if a user "pull to refresh"
Performance requires minimal code
Plugins and libraries have to be written to be as flexible and general as possible, in order to solve many related problems. This means they'll always be bulkier than you need, impacting performance. It also means you'll never have to maintain that code. That's the trade off.
If performance is your goal, build it yourself.
Since ALL you need is a pull-down detection, build a simple swipe detector.
Of course, you'll have to adapt this to your needs, and the event-properties, event-triggers of the OS and browser you're targeting.
Simplified from my old js-minimal-swipe-detect
var pStart = { x: 0, y: 0 };
var pStop = { x: 0, y: 0 };
function swipeStart(e) {
if (typeof e["targetTouches"] !== "undefined") {
var touch = e.targetTouches[0];
pStart.x = touch.screenX;
pStart.y = touch.screenY;
} else {
pStart.x = e.screenX;
pStart.y = e.screenY;
}
}
function swipeEnd(e) {
if (typeof e["changedTouches"] !== "undefined") {
var touch = e.changedTouches[0];
pStop.x = touch.screenX;
pStop.y = touch.screenY;
} else {
pStop.x = e.screenX;
pStop.y = e.screenY;
}
swipeCheck();
}
function swipeCheck() {
var changeY = pStart.y - pStop.y;
var changeX = pStart.x - pStop.x;
if (isPullDown(changeY, changeX)) {
alert("Swipe Down!");
}
}
function isPullDown(dY, dX) {
// methods of checking slope, length, direction of line created by swipe action
return (
dY < 0 &&
((Math.abs(dX) <= 100 && Math.abs(dY) >= 300) ||
(Math.abs(dX) / Math.abs(dY) <= 0.3 && dY >= 60))
);
}
document.addEventListener(
"touchstart",
function (e) {
swipeStart(e);
},
false
);
document.addEventListener(
"touchend",
function (e) {
swipeEnd(e);
},
false
);
What about this?
var lastScrollPosition = 0;
window.onscroll = function(event)
{
if((document.body.scrollTop >= 0) && (lastScrollPosition < 0))
{
alert("refresh");
}
lastScrollPosition = document.body.scrollTop;
}
If your browser doesn't scroll negative, then you could replace line 4 with something like this:
if((document.body.scrollTop == 0) && (lastScrollPosition > 0))
Alternatively for android devices, you could swap out lastScrollPosition for "ontouchmove" or other gesture events.
have you tired these solutions??
You need to check this fiddle
var mouseY = 0
var startMouseY = 0
$("body").on("mousedown", function (ev) {
mouseY = ev.pageY
startMouseY = mouseY
$(document).mousemove(function (e) {
if (e.pageY > mouseY) {
var d = e.pageY - startMouseY
console.log("d: " + d)
if (d >= 200) location.reload()
$("body").css("margin-top", d / 4 + "px")
} else $(document).unbind("mousemove")
})
})
$("body").on("mouseup", function () {
$("body").css("margin-top", "0px")
$(document).unbind("mousemove")
})
$("body").on("mouseleave", function () {
$("body").css("margin-top", "0px")
$(document).unbind("mousemove")
})
and if you are looking for some plugin this plugin might help you
I know this answer has been answered by a lot many people but it may help someone.
It's based on Mr. Pryamid's answer. but his answer does not work touch screen. that only works with mouse.
this answer works well on touch screen and desktop. i have tested in chrome in desktop and chrome in android
<!DOCTYPE html>
<html>
<head>
<style>
* {
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
}
.pull-to-refresh-container {
width: 100%;
height: 100%;
background-color: yellow;
position: relative;
}
.pull-to-refresh-content-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: white;
margin: 0px;
text-align: center;
}
</style>
</head>
<body>
<div class="pull-to-refresh-container">
<div class="pull-to-refresh-loader-container">
loading ...
</div>
<div class="pull-to-refresh-content-container">
here lies the content
</div>
</div>
<script>
var mouseY = 0
var startMouseY = 0
var container = document.querySelector(
".pull-to-refresh-content-container"
)
container.onmousedown = (ev) => {
mouseY = ev.pageY
startMouseY = mouseY
container.onmousemove = (e) => {
if (e.pageY > mouseY) {
var d = e.pageY - startMouseY
console.log("d: " + d)
container.style.marginTop = d / 4 + "px"
if (d >= 300) {
// alert("load more content");
}
} else {
container.onmousemove = null
}
}
}
container.onmouseup = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
container.onmouseleave = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
container.ontouchstart = (ev) => {
mouseY = ev.touches[0].pageY
startMouseY = mouseY
container.ontouchmove = (e) => {
if (e.touches[0].pageY > mouseY) {
var d = e.touches[0].pageY - startMouseY
console.log("d: " + d)
container.style.marginTop = d / 4 + "px"
if (d >= 300) {
// alert("load more content");
}
} else {
container.onmousemove = null
}
}
}
container.ontouchcancel = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
container.ontouchend = (ev) => {
container.style.marginTop = "0px"
container.onmousemove = null
}
</script>
</body>
</html>
Here is how I did it with Stimulus and Turbolinks:
See video in action: https://imgur.com/a/qkzbhZS
import { Controller } from "stimulus"
import Turbolinks from "turbolinks"
export default class extends Controller {
static targets = ["logo", "refresh"]
touchstart(event) {
this.startPageY = event.changedTouches[0].pageY
}
touchmove(event) {
if (this.willRefresh) {
return
}
const scrollTop = document.documentElement.scrollTop
const dy = event.changedTouches[0].pageY - this.startPageY
if (scrollTop === 0 && dy > 0) {
this.logoTarget.classList.add("hidden")
this.refreshTarget.classList.remove("hidden")
if (dy > 360) {
this.willRefresh = true
this.refreshTarget.classList.add("animate-spin")
this.refreshTarget.style.transform = ""
} else {
this.refreshTarget.classList.remove("animate-spin")
this.refreshTarget.style.transform = `rotate(${dy}deg)`
}
} else {
this.logoTarget.classList.remove("hidden")
this.refreshTarget.classList.add("hidden")
this.refreshTarget.classList.remove("animate-spin")
this.refreshTarget.style.transform = ""
}
}
touchend(event) {
if (this.willRefresh) {
Turbolinks.visit(window.location.toString(), { action: 'replace' })
} else {
this.logoTarget.classList.remove("hidden")
this.refreshTarget.classList.add("hidden")
this.refreshTarget.classList.remove("animate-spin")
this.refreshTarget.style.transform = ""
}
}
}
body(class="max-w-md mx-auto" data-controller="pull-to-refresh" data-action="touchstart#window->pull-to-refresh#touchstart touchmove#window->pull-to-refresh#touchmove touchend#window->pull-to-refresh#touchend")
= image_tag "logo.png", class: "w-8 h-8 mr-2", "data-pull-to-refresh-target": "logo"
= image_tag "refresh.png", class: "w-8 h-8 mr-2 hidden", "data-pull-to-refresh-target": "refresh"
One simple way:
$(document.body).pullToRefresh(function() {
setTimeout(function() {
$(document.body).pullToRefreshDone();
}, 2000);
});
I have a code that works just fine to check if element is outside of bottom viewport, as follows:
function posY(elm) {
let test = elm, top = 0;
while(!!test && test.tagName.toLowerCase() !== "body") {
top += test.offsetTop;
test = test.offsetParent;
}
return top;
}
function viewPortHeight() {
let de = document.documentElement;
if(!window.innerWidth)
{ return window.innerHeight; }
else if( de && !isNaN(de.clientHeight) )
{ return de.clientHeight; }
return 0;
}
function scrollY() {
if( window.pageYOffset ) { return window.pageYOffset; }
return Math.max(document.documentElement.scrollTop, document.body.scrollTop);
}
function checkvisible (elm) {
let vpH = viewPortHeight(), // Viewport Height
st = scrollY(), // Scroll Top
y = posY(elm);
return (y > (vpH + st));
}
if (hasActivity && isHidden) {
isVisibleCSS = <div className='onscreen'>More activity below ↓</div>;
} else if (hasActivity && !isHidden) {
//technically, there's no need for this here, but since I'm paranoid, let's leave it here please.
}
My question is, how can I adapt this code or create a new one similar to this one that identifies when element is outside of top viewport?
Cheers.
For an element to be completely off the view top then the sum of the element's top offset and it's height, like in this JS Fiddle
var $test = document.getElementById('test'),
$tOffset = $test.offsetTop,
$tHeight = $test.clientHeight,
$winH = window.innerHeight,
$scrollY;
window.addEventListener('scroll', function() {
$scrollY = window.scrollY;
if ($scrollY > ($tOffset + $tHeight)) {
console.log('out of the top');
}
});
body {
margin: 0;
padding: 0;
padding-top: 200px;
height: 1500px;
}
#test {
width: 100px;
height: 150px;
background-color: orange;
margin: 0 auto;
}
<div id="test"></div>
Essentially, I keep getting the message "document is not defined" when I run my .js doc on command line. I'm trying to create a super basic game where the user helps the squirrel get to the chestnuts by using arrow keys. So far I can't move the squirrel yet, and I suspect it has to do with the document is not defined error that I'm getting (lines 1-3 and maybe also 52 in the link).
You can find my code (html, css and js) in the following jsfiddle link
(http://jsfiddle.net/8Lbkcsq2/)
var squirrelImg = document.getElementById("squirrelImg");
var forest = document.getElementById("forest");
var chestnutImg = document.getElementById("chestnutsImg");
var squirrel = {
name: "Mr. Squirrel",
has_chestnuts: false,
hungry: true
};
var chestnuts = {
name: "chestnuts"
};
var positionLeft = 0;
var positionTop = 0;
function move(e) {
// 39 for right arrow
if (e.keyCode === 39) {
if (positionLeft < 850) {
positionLeft += 50;
squirrelImg.style.left = positionLeft + "px";
}
}
// 40 for down arrow
if (e.keyCode === 40) {
if (positionTop < 600) {
positionTop += 50;
squirrelImg.style.top = positionTop + "px";
}
}
// 37 for left arrow
if (e.keyCode === 37) {
positionLeft -= 50;
if (positionLeft < 0) {
positionLeft += 50; // CHANGE TO +=50 LATER
}
squirrelImg.style.left = positionLeft + "px";
}
// 38 for up arrow
if (e.keyCode === 38) {
positionTop -= 100;
if (positionTop < 0) {
positionTop += 50; // CHANGE TO +=50 LATER
}
squirrelImg.style.top = positionTop + "px";
}
foundChestnuts();
}
document.onKeyDown = move();
function foundChestnuts() {
if ((squirrelImg.style.top == "300px") && (squirrelImg.style.left == "750px")) {
squirrel.has_chestnuts = true;
alert("Thank you for helping Mr. Squirrel find his chestnuts!");
var eat = confirm("Should Mr.Squirrel eat his chestnuts?");
if (eat === true) {
alert("Time to eat!");
alert("Yum! Mr. Squirrel isn't hungry anymore!");
} else {
alert("I guess Mr. Squirrel can wait a little longer...");
}
} else {
squirrel.has_chestnuts = false;
}
}
body {
background-color: #b5916c;
}
h3 {
font-weight: bold;
text-decoration: underline;
}
p {
font-family:'Dancing Script', cursive;
font-size: large;
}
#forest {
background-image: url(http://s21.postimg.org/jyht762hj/forestfloor.jpg);
width: 850px;
height: 600px;
position: relative;
/*opacity: 0.5;*/
}
#squirrelImg {
position: absolute;
background-image: url(http://s24.postimg.org/wkqh9by4x/squirrel.png);
height: 100px;
width: 100px;
left: 0;
top: 0;
}
#chestnutsImg {
position: absolute;
background-image: url(http://s28.postimg.org/kgiubxhnd/chestnuts.jpg);
height: 100px;
width: 100px;
left: 750px;
top: 300px;
}
<body>
<h3>A Plea from Mr. Squirrel:</h3>
<p>My dearest human,</p>
<p>I seem to have misplaced my chestnuts and I am quite famished.</p>
<p>Would you mind assisting me in locating them?</p>
<p>Much obliged!</p>
<div id="forest">
<div id="squirrelImg"></div>
<div id="chestnutsImg"></div>
</div>
</body>
The issue is that move() requires an event to be passed to it but when you do document.onKeyDown = move(); no event is passed.
Change document.onKeyDown = move(); to document.addEventListener("keydown", move, false);
working jsfiddle
Add a event listener document.body.addEventListener('keydown', function(e) {...} instead of document.onKeyDown = move().
Updated Fiddle
var squirrelImg = document.getElementById("squirrelImg");
var forest = document.getElementById("forest");
var chestnutImg = document.getElementById("chestnutsImg");
var squirrel = {
name: "Mr. Squirrel",
has_chestnuts: false,
hungry: true
};
var chestnuts = {
name: "chestnuts"
};
var positionLeft = 0;
var positionTop = 0;
document.body.addEventListener('keydown', function(e) {
// 39 for right arrow
if (e.keyCode === 39) {
if (positionLeft < 850) {
positionLeft += 50;
squirrelImg.style.left = positionLeft + "px";
}
}
// 40 for down arrow
if (e.keyCode === 40) {
if (positionTop < 600) {
positionTop += 50;
squirrelImg.style.top = positionTop + "px";
}
}
// 37 for left arrow
if (e.keyCode === 37) {
positionLeft -= 50;
if (positionLeft < 0) {
positionLeft += 50; // CHANGE TO +=50 LATER
}
squirrelImg.style.left = positionLeft + "px";
}
// 38 for up arrow
if (e.keyCode === 38) {
positionTop -= 100;
if (positionTop < 0) {
positionTop += 50; // CHANGE TO +=50 LATER
}
squirrelImg.style.top = positionTop + "px";
}
foundChestnuts();
});
// combined 3 functions previously separated for foundChestnuts, eatChestnuts and hungerLevel into the function below
function foundChestnuts() {
if ((squirrelImg.style.top == "300px") && (squirrelImg.style.left == "750px")) {
squirrel.has_chestnuts = true;
alert("Thank you for helping Mr. Squirrel find his chestnuts!");
var eat = confirm("Should Mr.Squirrel eat his chestnuts?");
if (eat === true) {
alert("Time to eat!");
alert("Yum! Mr. Squirrel isn't hungry anymore!");
} else {
alert("I guess Mr. Squirrel can wait a little longer...");
}
} else {
squirrel.has_chestnuts = false;
}
}
body {
background-color: #b5916c;
}
h3 {
font-weight: bold;
text-decoration: underline;
}
p {
font-family: 'Dancing Script', cursive;
font-size: large;
}
#forest {
background-image: url(http://s21.postimg.org/jyht762hj/forestfloor.jpg);
width: 850px;
height: 600px;
position: relative;
/*opacity: 0.5;*/
}
#squirrelImg {
position: absolute;
background-image: url(http://s24.postimg.org/wkqh9by4x/squirrel.png);
height: 100px;
width: 100px;
left: 0;
top: 0;
}
#chestnutsImg {
position: absolute;
background-image: url(http://s28.postimg.org/kgiubxhnd/chestnuts.jpg);
height: 100px;
width: 100px;
left: 750px;
top: 300px;
}
<body>
<h3>A Plea from Mr. Squirrel:</h3>
<p>My dearest human,</p>
<p>I seem to have misplaced my chestnuts and I am quite famished.</p>
<p>Would you mind assisting me in locating them?</p>
<p>Much obliged!</p>
<div id="forest">
<div id="squirrelImg"></div>
<div id="chestnutsImg"></div>
</div>
</body>
please place the script before </body>, or in window.onload callback function.
Because document object is not created when you call document.getElementById.
Yes, the problem is document.onKeyDown = move(). The right event handler isdocument.onkeydown, and handler should be a function move, not a function result move(). So just changed to document.onkeydown=move