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

Create a PDF document and provide a reply

Recently, I encountered an issue while trying to generate a PDF using KnpSnappyBundle on Symfony. Upon running a route through AJAX, the code executes without errors but fails to produce the PDF file. The objective is to create a PDF in a new tab or wind ...

Regular expressions should be utilized in a way that they do not match exactly with a

Can someone help me create a regular expression for an html5 input pattern attribute that excludes specific items? How can I convert ab aba ba into a pattern that will match anything that is not exactly one of these words? For example, I want the fol ...

How to populate the space beneath the `AreaChart` curve in `recharts` when data includes positive and negative values

How can I modify my chart, created using the recharts library in JavaScript, so that the area under the curve fills to the bottom of the visible area instead of stopping at zero? This is how it currently looks: My goal is to have the curve fill all the w ...

The attempt to install "expo-cli" with the command "npm install -g expo-cli" was unsuccessful

Encountered an issue while trying to install expo-cli for creating android applications using npm install -g expo-cli. NPM version: 7.19.1 Node version: v15.14.0 Upon running npm install -g expo-cli, the installation failed with the following error mess ...

I encountered an issue stating, "The function `req.redirect` is not recognized."

Recently starting out with node development. Encountering the error below: TypeError: req.redirect is not a function at Post.create (/var/www/html/node_blog/index.js:40:7) at /var/www/html/node_blog/node_modules/mongoose/lib/utils.js:276:16 a ...

Mysterious obsidian container lurking in the background of the video on Chrome version 67.0.3396

Displayed on the page is an HTML Video tag, which streams a video from the speaker (WebRTC). <div id="remoteVideoContainer"> <video id="remotevideo" autoplay="autoplay" controls="" loop="loop" preload="true" height="500" width="100%"> ...

Incorporate Calendly Script into your NextJs application

I'm currently working on integrating Calendly into my Next.js project. However, I am unsure about the process. My goal is to embed it on a specific page rather than in _app or _document. Here is what I have attempted so far: import Script from &apos ...

What is the process for utilizing GruntFile.coffee and package.json to extract or create the Lungo.js example files?

I want to experiment with the Lungo.js examples found here: https://github.com/tapquo/Lungo.js. However, when I try to run the index.html in the example directory, it seems like the components and package directories are empty. Although these directories d ...

Utilizing jQuery to Bind AJAX Events without a DOM Element

The documentation for jQuery AJAX Events provides examples that all involve using a jQuery DOM Element to declare a binding, like so: $('.log').ajaxSend( hander ); I am interested in capturing jQuery AJAX Events without the need for a DOM Eleme ...

Enhancing the background of a website with the power of CSS

I am looking to create a customized table without the balls/pots in it. The number of rows on the y-axis will vary depending on the number of names I have, and can be more or less. The values on the x-axis are determined by a parameter included in the URL ...

The error callback for Ajax is triggered even though the JSON response is valid

Within my JavaScript file, I am making the following call: $.ajax({ type: "POST", dataType: "application/json", url: "php/parseFunctions.php", data: {data:queryObj}, success: function(response) { ...

AngularJS selection controls: checkbox and dropdown menus

Can someone provide an example that includes a dropdown menu and checkboxes? The options in the checkbox list should match the data in the dropdown. Once a value is selected from the dropdown, the corresponding checkbox option should be automatically chec ...

A guide to organizing page components across multiple `/pages` directories in a Next.js application

As I delve into my first project using Next.js, I find that my pages directory has expanded significantly. Now, I am keen on organizing my pages by grouping them into modules, resulting in a structure like 'src/modules/*/pages/*'. In my quest fo ...

Storing Documents on Your Device

I've been working on a project to create a web page that provides links to online PDF files. When you click on these links, the file should be saved locally and its name/path added to local storage. I then aim to display all the saved files by iterati ...

Just starting out with Angular - facing issues with setting up in eclipse

I'm attempting to create a test Angular project in Eclipse by copying the three files from the Angular website https://docs.angularjs.org/api/ng/directive/ngController into my Eclipse project. I initially created it as a static web project and then co ...

Difficulty in updating Vue variable value following a request

Hello everyone, I am facing an issue regarding a variable value. Within the request, I am comparing each array value to see if there is a match and then updating the match variable to true if a match is found. However, the problem arises when the updated ...

reveal one div and conceal another using Bootstrap's collapse feature

I'm not sure why it's not working. Maybe I missed some simple thing? I want to show one div when I use an icon, then hide the other div. Currently, if I click on the first icon, a div will show. But if I click on the second icon, the div will sh ...

Implementing conditional ng-show based on checkbox status in AngularJS

I have created this code to filter out the out-of-stock products using ng-show. When the checkbox is checked, only the available products should be displayed. HTML: <input type="checkbox" id="chkStock" value="Exclude Out of Stock" ng-model="exclude" / ...

`Cannot recompile the `Product` model as it has already been compiled. Please try again

I attempted to reference my productSchema within my purchaseSchema but encountered the following error: OverwriteModelError: Cannot overwrite Product model once compiled. What steps can I take to resolve this issue? Here is my product schema: mongoose = ...

What is the best way to incorporate multiple pages into a Node JS and Express application?

After completing a tutorial on Node JS for RPI (https://www.youtube.com/watch?v=QdHvS0D1zAI), I encountered an issue when trying to add multiple websites to my web app. While everything works fine locally on localhost:5000/page2, once I make the app public ...