Create a spinner control on an HTML webpage with the help of JavaScript

I am attempting to create a spinner control on my webpage, and I have tried the following code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Simple spinner</title>

    <script type="text/javascript">
        function RotateSpinner(spinnerId, up) {
            var ele=document.getElementById(spinnerId);
            ele.value=parseInt(ele.value)+up;
                var t=setTimeout(function(){
                    if(window.rotate_start)
                        RotateSpinner(spinnerId,up);
                    else
                        clearTimeout(t);
                },500);

        }


    </script>

    <style>
        *
        {
            padding: 0;
            margin: 0;
        }
        .spinner
        {
            list-style: none;
            display: inline-block;
            line-height: 0;
            vertical-align: middle;
        }
        .spinner input
        {
            font-size: .45em;
            border-width: .5px;
            height: 1.5em;
            width: 2em;
        }
    </style>
</head>
<body>
    <input id="spinner" type="text" value="0" />
    <ul class="spinner">
        <li>
            <input type="button" value="&#9650;" onmousedown="window.rotate_start=true;RotateSpinner('spinner', 1)" onmouseup="window.rotate_start=false;"/>
        </li>
        <li>
            <input type="button" value="&#9660;" onmousedown="window.rotate_start=true;RotateSpinner('spinner', -1)" onmouseup="window.rotate_start=false;"/>
        </li>
    </ul>
</body>
</html>

However, the spinner does not behave as expected. When I click the "up" button, I want the value to increment only once, but sometimes it adds the value multiple times.

Could someone please review this and make the necessary fixes?

For a live example, visit this link

Answer №1

Utilizing an interval can streamline the code significantly, as confirmed through testing on IE9, Chrome21, and FF14. I conducted my testing using http://jsfiddle.net/KmMCE/3/, although I have yet to update the sample.

Here is the markup:

    <input id="spinner" type="text" value="0" />
    <input type="button" value="&#9650;"
      onmousedown="spinnerMouseDown('spinner', 1);" 
onmouseup="stopSpinner();" onmouseout="stopSpinner();" />

    <input type="button" value="&#9660;"
      onmousedown="spinnerMouseDown('spinner', -1);" 
onmouseup="stopSpinner();" onmouseout="stopSpinner();" />

The JavaScript snippet is as follows:

function spinnerMouseDown(id, value) {
    var el = document.getElementById(id);
    window.spinnerTimer = window.setInterval(function(){
      el.value = parseInt(el.value) + value;
    }, 100);
}

function stopSpinner() {
    window.clearInterval(window.spinnerTimer);
}

Answer №2

Here are the key issues that need to be addressed:

  • The handling of the onmouseup and onmousedown events needs improvement.

    • An onmousedown event in a button can still trigger even if the subsequent onmouseup event occurs outside the button. This results in inaccurate tracking of the window.rotate_start variable. Simply relying on onmouseup and onmousedown events is insufficient for achieving the desired functionality.

    • To resolve this, implement a global event handler for both onmouseup and onmousedown events that maintains the state in a variable. Additionally, use other variables to monitor the occurrence of onmouseover and onmouseout events on the buttons. This will help determine whether to update the value or not, along with how to adjust it (+1/-1).

  • Accumulation of timeouts during single clicks is causing undesired effects as mentioned in the question. To address this issue, introduce a variable that tracks whether a timeout has been set, and reset the timeout when both onmousedown and onmouseover events for a button are triggered (i.e., upon a single click, disregard any pending timer executions).

For a practical example, refer to the following fiddle: http://jsfiddle.net/KmMCE/3/

<input type="button" value="&#9650;"
        onmouseover="window.upfocus = 1;" onmouseout="window.upfocus = 0;" />

<input type="button" value="&#9660;"
            onmouseover="window.downfocus = 1;" onmouseout="window.downfocus = 0;" />

var timingOut = false;
var upfocus = 0;
var downfocus = 0;
var mouseDown = 0;
document.body.onmousedown = function() {

    mouseDown = 1;
    if (window.upfocus == 1) {
        if (timingOut) {
            clearTimeout(t);
            timingOut = false;
        }
        RotateSpinner('spinner', 1);
    }
    else if (window.downfocus == 1) {
        if (timingOut) {
            clearTimeout(t);
            timingOut = false;
        }
        RotateSpinner('spinner', -1);
    }
}
document.body.onmouseup = function() {
    mouseDown = 0;
}

function RotateSpinner(spinnerId, up) {
    var ele = document.getElementById(spinnerId);
    ele.value = parseInt(ele.value) + up;
    timingOut = true;
    t = setTimeout(function() {
        if (mouseDown == 1 && up == 1 && window.upfocus == 1) {
            RotateSpinner(spinnerId, up);
        }
        else if (mouseDown == 1 && up == -1 && window.downfocus == 1) {
            RotateSpinner(spinnerId, up);
        }
        else {
            clearTimeout(t);
            timingOut = false;
        }
    }, 500);

}

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

I am attempting to assign a default value to a TextField by retrieving data from a GetMapping call in React, however, the value is not being successfully set

I am facing an issue with setting a default value for a TextField in my code. Even though I am trying to populate it with data from a GetMapping call, the value is not being set as expected. Here is the JSON response I receive from the API call: { "id": 1 ...

Oops! Looks like there was an issue with defining Angular in AngularJS

I am encountering issues while attempting to launch my Angular application. When using npm install, I encountered the following error: ReferenceError: angular is not defined at Object.<anonymous> (C:\Users\GrupoBECM18\Documents&bs ...

What is the method of displaying a querystring on my Angular view page without relying on a controller?

My experience lies in utilizing AngularJS 1. This excerpt showcases the stateprovider configuration present in my config.js file: JavaScript .state('projects', { abstract: true, url: "/projects", templateUrl: "views/common/master_pa ...

Issue with content overlapping when hamburger icon is tapped on mobile device

When the hamburger menu is pressed on smaller screens, I want my navbar to cover the entire screen. To achieve this, I included the .push class in my code (see the jQuery and CSS) to trigger when the .navbar-toggle-icon is pushed. However, after implemen ...

Attempting to alter an image with a click and then revert it back to its original state

I'm currently working on a feature that toggles an image when a specific class is clicked. The code I have so far successfully switches from 'plus.png' to 'minus.png' upon clicking, but I need it to switch back to 'plus.png&ap ...

Error: OpenAI's transcription API has encountered a bad request issue

const FormData = require('form-data'); const data = new FormData(); console.log('buffer: ', buffer); console.log('typeof buffer: ', typeof buffer); const filename = new Date().getTime().toString() + '.w ...

Dealing with VueJS - Sharing an array of data from a child to a parent component using v-model

I am facing an issue in emitting data (array) from a child component to a parent component using v-model. However, when the parent component is created, my console.log does not work. I am hesitant to work with Vuex as I am still a beginner. Here is my chi ...

Exploring the implementation of Chain Map or Chain Filter within an Angular Http request that delivers a promise

I have a dataset in JSON format that I am working with, and I need to filter out specific key values using lodash. I want to reject multiple keys that I don't need. My initial approach is to either chain the map function and then use the reject funct ...

Choose all the alternative A radio buttons utilizing JavaScript

If the "4 stars" option is selected at the top, I want all corresponding "4 stars" options in the form to be automatically selected. Similarly, if "3 stars" is chosen, I need all the "3 stars" options to be selected. I attempted to achieve this functionali ...

AngularJS UI.Router ActiveState implemented with a dropdown menu feature

I am currently working on creating a menu with dropdown functionality for multiple links within my application. My goal is to have the dropdown menu display as "active" when one of the links below is active. I have managed to make either the link in the ...

I have successfully implemented the Context API in my Next.js project and everything is functioning smoothly. However, I encountered an error while using TypeScript

Currently, I am working on a Next.js project that involves using the Context API. The data fetched from the Context API works perfectly fine, but I am encountering errors with TypeScript and I'm not sure how to resolve them. Error: Property openDialo ...

Using JavaScript, you can filter an array of objects based on a specific search input

I am in the process of implementing a filtering feature for a list using React, but surprisingly, I haven't been able to find any useful resources online to guide me through this common task. Currently, I have an array of users that I need to filter ...

Generating pop-up upon loading with CSS3

I have searched through numerous threads and forums in the hopes of finding a solution, but I haven't been successful. My issue lies with triggering a popup on my website. I followed online tutorials to create a popup window, which I was able to do su ...

How to Handle Tab Navigation on a Mobile Website without Javascript?

My website primarily targets mobile devices, with tabs in the top navigation. Currently, these tabs are hard coded instead of utilizing Javascript. We want to ensure our site is accessible on all mobile devices, including those without Javascript support. ...

Node.js MySQL REST API query fails to execute

I am developing a login/sign up API using nodejs, express, and mysql. Despite receiving the "Successful Sign Up!" message without any errors during testing, the user table in the database remains empty. Below is the query I am attempting to execute: con. ...

Implement lazy loading functionality in Django to dynamically load data as the user scrolls

Currently, I am developing a web application using Django to showcase the interface and how content is loaded. In my database, there could potentially be thousands of entries, and I am looking for a way to load only a certain number at a time to minimize ...

How to create a vertically scrollable div within another div by utilizing scrollTop in jQuery

I need assistance with scrolling the #container div inside the .bloc_1_medias div. The height of #container is greater than that of .bloc_1_medias. My goal is to implement a function where clicking on the "next" and "previous" text will scroll the #contai ...

I'm struggling to make this background show up in a div

Anyone able to help me figure this out? I can't seem to get the achtergrond_homepage.png as a background in rounded corners. Edit: It seems like the gray color is always on top. Could it be controlled in the JavaScript part? This is the CSS: @ch ...

Replace the value of Undefined with an empty string

I have been utilizing exif.js to extract metadata from the images I upload on a content management system (CMS). However, sometimes when an image does not contain any metadata, certain values may show up as "undefined". My goal is to replace these "undefin ...

submission of form data and automatic redirection to another page

Seeking advice on managing form submissions and page redirection. I have a landing page with a basic form, where users select criteria and are then redirected to page2 displaying tabular data and query information. When submitting the form on Page1, data ...