Javascript - Button animation malfunctioning after first click

One issue I'm facing is with an animation that is triggered using the onmousedown event. Another function is supposed to stop the animation when onmouseup is detected.

The problem arises after the first time it works correctly. Subsequent attempts to use the buttons fail to trigger any movement. It just seems to get stuck.

Below is my HTML code (index.htm):

<html>
<head><link rel='stylesheet' href='style.css'></head>
<body>
    <img id='player' src='img/player.png' style='height:64px;'></img>
    <div class='buttons'>
        <button id='moveleft' onmousedown="OnButtonDownl (this)" onmouseup="OnButtonUpl (this)"><--</button>
        <button id='moveright' onmousedown="OnButtonDownr (this)" onmouseup="OnButtonUpr (this)">--></button>
    </div>
</body>
</html>


<script type='text/javascript' src='move.js'></script>

This is my javascript code (move.js):

var elem = document.getElementById("player");
function OnButtonDownl (button) {
var posl = document.getElementById("player").style.left;
window.idl = setInterval(framel, 5);
function framel() {
    posl--;
    elem.style.left = posl + 'px';
}}
function OnButtonUpl (button) {
    clearInterval(idl);
}

var elem = document.getElementById("player");
function OnButtonDownr (button) {
var posr = document.getElementById("player").style.left;
window.idr = setInterval(framer, 5);
function framer() {
    posr++;
    elem.style.left = posr + 'px';
}}
function OnButtonUpr (button) {
    clearInterval(idr);
}

Just for reference, here is my css (style.css):

body {
  width: 100%;
  height: 100%;
position:relative;
margin:0;
overflow:hidden;
}
#player {
  position: absolute;
  left:0;
  bottom:0;
}
.buttons {
position:absolute;
right:0;
bottom:0;
}

Any assistance would be greatly appreciated.

Answer №1

You are encountering two specific issues.

  1. Initially, when you retrieve the values for posl and posr, it results in an empty string which is coerced to 0 by JavaScript.
  2. Subsequently, the use of -- and ++ operations fails after adding px to the values of posl and posr, turning them into strings.

The expression posl-- (or posr++) can increment the coerced value of

0</code successfully. This explains why it works on the first iteration. However, upon the next <code>mousedown
event,
document.getElementById("player").style.left
now holds a string like "-1px" which does not coerce to
0</code. To remedy this, you can utilize <code>parseInt()
when storing the values of posl and posr, with a fallback value of 0 provided, as parseInt("") returns NaN.

To address this issue properly, consider making similar adjustments when handling the value of posr:

var posl = parseInt( document.getElementById("player").style.left, 10 ) || 0;

var elem = document.getElementById("player");

function OnButtonDownl(button) {
  //var posl = document.getElementById("player").style.left;
  var posl = parseInt(document.getElementById("player").style.left, 10) || 0;
  window.idl = setInterval(framel, 5);

  function framel() {
    posl--;
    elem.style.left = posl + 'px';
  }
}

function OnButtonUpl(button) {
  clearInterval(idl);
}

var elem = document.getElementById("player");

function OnButtonDownr(button) {
  //var posr = document.getElementById("player").style.left;
  var posr = parseInt(document.getElementById("player").style.left, 10) || 0;
  window.idr = setInterval(framer, 5);

  function framer() {
    posr++;
    elem.style.left = posr + 'px';
  }
}

function OnButtonUpr(button) {
  clearInterval(idr);
}
body {
  width: 100vw;// changed for example only
  height: 100vh;// changed for example only
  position: relative;
  margin: 0;
  overflow: hidden;
}
#player {
  position: absolute;
  left: 0;
  bottom: 0;
}
.buttons {
  position: absolute;
  right: 0;
  bottom: 0;
}
<img id='player' src='//placekitten.com/102/102' />
<div class='buttons'>
  <button id='moveleft' onmousedown="OnButtonDownl (this)" onmouseup="OnButtonUpl (this)">Left</button>
  <button id='moveright' onmousedown="OnButtonDownr (this)" onmouseup="OnButtonUpr (this)">Right</button>
</div>

Answer №2

I revised your code and it is now functioning properly (at least for me).

function Move(elem){
    this.interval;

    var posr = parseInt(getComputedStyle(document.getElementById("player")).left);

    this.handleEvent = function(event) {
      switch (event.type) {
        case 'mousedown':
            this.interval = setInterval(function() {
                if (event.target.id == 'moveright') {
                    posr++;
                } else if (event.target.id == 'moveleft'){
                    posr--;
                }
                document.getElementById("player").style.left = posr + 'px';

            },5);
            break;
        case 'mouseup':
            clearInterval(this.interval);
            break;
      }
  }
  elem.addEventListener('mousedown', this,  false);
  elem.addEventListener('mouseup', this,  false);

}

var button_right = document.getElementById("moveright");
var button_left = document.getElementById("moveleft");

Move(button_right);
Move(button_left);

Additionally, in the HTML you can remove JavaScript event listeners (only the IDs are necessary).

Answer №3

It's considered good practice to ensure that your script tag is placed within your html tags:

<html>
<head>...</head>
<body>...</body>
    <script type='text/javascript' src='move.js'></script>
</html>

Once you've done that, try out this solution:

HTML:

<html>
<head><link rel='stylesheet' href='style.css'></head>
<body>
    <img id='player' src='https://placeimg.com/54/45/any' style='height:64px;'></img>
    <div class='buttons'>
        <button id='moveleft' onmousedown="OnButtonDown('left')" onmouseup="OnButtonUp()"><--</button>
        <button id='moveright' onmousedown="OnButtonDown('right')" onmouseup="OnButtonUp()">--></button>
    </div>

<script type='text/javascript' src='move.js'></script>
</body>
</html>

And here's the corresponding JavaScript code:

var nIntervId;
var b;
var elem = document.getElementById("player");

var posl = document.getElementById("player").style.left;

function OnButtonDown(button) {
b = button;
nIntervId = setInterval(frame, 5);
}

function frame() {
  if(b==='left'){
    posl--;
    elem.style.left = posl + 'px';}
  else{
    posl++;
    elem.style.left = posl + 'px';
  }
}

function OnButtonUp() {
    clearInterval(nIntervId);
}

Visit this link for a live demo of the code.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using HTML5's getCurrentPosition function with Meteor

Attempting to utilize the html5 geolocation api within Meteor. Executing: navigator.geolocation.getCurrentPosition(handle_geolocation_query); in my javascript code but encountering issues - suspect it could be tied to the restrictions on timing ( ) enfo ...

Having trouble getting my local website to load the CSS stylesheet through Express and Node.js in my browser

https://i.stack.imgur.com/qpsQI.png https://i.stack.imgur.com/l3wAJ.png Here is the app.js screenshot: https://i.stack.imgur.com/l3wAJ.png I have experimented with different combinations of href and express.static(""); addresses. However, I am ...

What is the best way to retrieve the post JSON data in the event of a 404 error?

When my service call returns a 404 error, I want to display the server's message indicating the status. The response includes a status code and message in JSON format for success or failure. This is an example of my current service call: this._trans ...

for each and every object, execute the asynchronous function

I have a scenario where I need to loop through objects, call an async method ("search") with a callback, and then write the results (resultSet) to a JSON file once all objects are processed. The issue I'm facing is that the writeFile function is execu ...

php json with multiple dimensions

Unable to retrieve the deepest values from my json object, which contains an array of images listed as: { "imgs":[ { "Landscape":{ "2":"DSCF2719.jpg", "3":"DSCF2775.jpg", "4":"IMG_1586.jpg", ...

How can you show a green check mark next to an input field in AngularJS after inputting valid data?

I am diving into the world of AngularJS and Angular Material with my web application. As a beginner in AngularJS and Angular Material, I need some help. My current task is to display a green checkmark next to an input field only when valid data is entere ...

Tips for displaying a Rails action without a layout in html format using Ajax

Is it possible to render the new action without the application layout and without altering the current code structure? class FoobarController < ApplicationController def new @foobar = Foobar.new end # ... end When a user clicks on = link_ ...

Internal server error frequently occurs when there is an issue with Ajax requests in a Laravel application

Greetings, fellow developers! I am encountering an issue with the comments system in Laravel and Ajax. While it functions correctly with PHP alone, I am facing difficulties when using Ajax. The error message I am receiving is as follows: Status Code:50 ...

Tips for incorporating tabs into a Rails 3 application with the help of Sass/Haml or CoffeeScript

Currently, I am looking to implement tabbed views in a project I am developing using Rails 3. To ensure compatibility with the latest features of Rails, I have decided to utilize Sass and CoffeeScript as my primary tools. If anyone has any resources or tu ...

Even though I have successfully stored a key value pair in LocalStorage using JSON stringify and setItem, the data does not persist after the page is refreshed

I recently developed a Todo application that runs smoothly, except for one crucial issue - the localStorage data does not persist after refreshing the page. Initially, the localStorage operations functioned properly when there were fewer event handlers in ...

Sharing and displaying images on Sails JS platform

Using Sails JS, I am attempting to upload an image and display it in a view. Queries: The uploaded image is located in .tmp/uploads, how can I retrieve it from a view? Is there a method to access the uploaded image? The image's name is altered in ...

Tips for achieving a blurred background image effect when hovering, while keeping the text unaffected

Hey there, I've recently started my journey into web development and have encountered a roadblock. I'm trying to blur the background image of a div on hover without affecting the text inside. I have an id called c1 where I used a javascript func ...

The table toggle feature seems to be malfunctioning in Safari, whereas it works perfectly in Chrome

My table includes a td element that serves as a toggle switch, transitioning between 3 states flawlessly in Chrome. However, I am facing issues with its functionality in Safari and seek assistance in rectifying the issue to ensure cross-browser compatibili ...

Experiencing a problem with value formatting while attempting to implement tremor for charts in React with Next.js version 13

import { getAuthSession } from "@/lib/auth"; import { db } from "@/lib/db"; import { Card, LineChart, Text, Title } from "@tremor/react"; import Linechart from "./LineChart"; const dollarFormatter = (value: number) ...

The attempt to create the property 'and_ff' on the string 'and_chr 89' has failed

Encountering an issue with a Lambda function, I receive an error that does not occur when running the same code within an Express app. I'm puzzled. Data returned by caniuse.getLatestStableBrowsers(); [ 'and_chr 89', 'and_ff 86& ...

Unique style pattern for parent links with both nested and non-nested elements

I am in the process of designing a website and I have a specific vision for how I want my links to appear, but I am unsure of how to achieve it. Here is the desired outcome: a red link a green link a red link a green link … Below is the HTM ...

Identify all td inputs within a TR element using jQuery

Is there a way to retrieve all the input values within each table cell (td) of a table row (tr) using jQuery? Suppose I have a tr with multiple td elements, and some of these tds contain inputs or select elements. How can I extract the values from these in ...

Trouble with z-index functionality in jQuery datatable

I'm struggling to get the Action Box displayed as an upper layer. I've already tried using z-index but it doesn't seem to make any difference. https://i.stack.imgur.com/rJ1vL.png $(document).ready(function () { ...

Retrieve the value from an input field when the value is returned from JavaScript

Scenario: I'm currently working on creating a QR reader to retrieve a specific value. You can check out the progress here: What's functioning: scanning. When I scan a QR code, a value is displayed in the text box. Here's the code snippet b ...

Guide on how to show the index value of an array on the console in Angular 2

Is there a way to show the array index value in the console window upon clicking the button inside the carousel component? The console seems to be displaying the index value twice and then redirecting back to the first array index value. Can we make it so ...