Activate click events when button is being held down

I'm currently working on a directive that shifts an element to the right whenever clicked. However, I want the element to keep moving as long as the button is pressed.

.directive("car", function(){
    return {
        restrict:"A",
        link:function(scope,element,attrs,controller){
            var left=0;
            var car = angular.element(element[0].querySelector('.car'));
            var move = function(e){
                left+=10;
                car[0].style.left = left+"px";
            };
            element.on("click", move);
        }
    };
})

My question is how can I continuously detect when the button is being pressed every half second and recall the move function? Is there a way to achieve smooth movement?

Check out an interactive demo here: http://jsfiddle.net/vtortola/2m8vD/

I am unable to use jQuery for this particular task, but I am open to utilizing AngularJS modules like ngTouch or any other alternative.

Answer №1

I created a simple mockup demonstrating a solution to your issue using mouseup and mousedown events along with the $timeout service.

.directive("car", function($timeout){
    return {
        restrict:"A",
        link:function(scope,element,attrs,controller){
            var left=0;
            var car = angular.element(element[0].querySelector('.car'));
            var timeout;
            var moveOnce= function() {
                left+=10;
                car[0].style.left = left+"px";
            };
            var move = function(e){
                $timeout.cancel(timeout);
                timeout = $timeout(function(){
                    moveALittle();
                    move();
                }, 250);
            };
            var stop = function(e){
                $timeout.cancel(timeout);
            };
            element.on("click", moveOnce);
            element.on("mousedown", move);
            element.on("mouseup", stop);

            element.on("$destroy",function(){
                element.off("click",moveOnce);
                element.off("mousedown", move);
                element.off("mouseup", stop);
            });
        }
    };
})

Check out the updated demo here: http://jsfiddle.net/2m8vD/12/

You can easily adjust the timeout delay and pixel movement for smoother motion according to your preference.

Instead of using mouseup and mousedown events, you can also utilize Angular directives ng-mouseup and ng-mousedown directly bound to the button element.

<button ng-mousedown="move" ng-mouseup="stop">Move</button>

UPDATE:
Introduced moveOnce() function for single-click functionality.

Answer №2

@Aaronias pointed me in the right direction, big thanks to him.

I successfully achieved fluid movement while holding down the button and made it cancellable when the mouse moves out. The key was eliminating the CSS transition, initiating an interval for incremental steps, and stopping that interval on mouseout or mouseup events.

var move = function(e){
    if(interval)
        return;

    step(e);
    mustStop = false;

    interval = $interval(function(){
        step(e);
        if(mustStop){
            $interval.cancel(interval);
            mustStop = false;
            interval = null;
        }
    }, 10);
};

var stop = function(){ mustStop= true;};

right.on("mousedown", move)
    .on("mouseup", stop)
    .on("mouseout", stop);

left.on("mousedown", move)
    .on("mouseup", stop)
    .on("mouseout", stop);

Here is the working version of the example: http://jsfiddle.net/vtortola/2m8vD/22/

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

ReactJS Application: Issue with Selective Mobile Scrolling

I've been working on a ReactJS web app where we mainly use styled-components for styling, but also sometimes utilize index.css for global styles (such as body and html). The application consists of an app header, a page header, and a container with a ...

Bower downloads the identical package but arranges it in a distinct file structure

We operate a TeamCity build server that is utilizing three different buildusers all configured similarly. We have integrated an angular/grunt project using yeoman Update 6 Noted an issue with bower https://github.com/bower/bower/issues/1709 Why does bow ...

Is there a way to verify HTML binding prior to setting up an AngularJS directive?

On a page where I utilized a custom select-box directive to display the Month, certain arguments are required by the directive: <custom-select-box id="month" model="month" model-required model-name="month" options="month.value ...

What sets apart the use of `function(){}.bind(this)` and `angular.bind(this, function() {})`

Can you highlight the difference between these two code snippets? function Ctrl($scope) { $scope.$watch(function() { return this.variable; }.bind(this), /*...*/); } and function Ctrl($scope) { $scope.$watch(angular.bind(this, functio ...

Change the right border style for the second and third ToggleButtons in the ToggleButtonGroup

I've been working on this for a few hours now and I can't seem to get it right. Currently, I'm using Mui v5 and trying to style the ToggleButtons to look like regular MUI buttons. So far, I was able to achieve this transformation: https:/ ...

Analyzing critical code paths for optimal performance

There is a function that accepts two arguments and an optional third argument. The function should return true if the first argument is greater than the second, false if not, unless the third argument is true, in which case it should return true if the fir ...

Initializing ng-app with a specific name will prevent the initialization of variables

Here is the code snippet I am working with: <div ng-app="" ng-init="show_login=false;count=0"> <button> ng-click="show_login=!show_login;count=count+1">INSPIRE</button> <form ng-show="show_login"> Username <input type="t ...

Tips for converting an object into parameters for ng-include

What is the best way to create a serialized array of objects that can be used as parameters for ng-include in order to dynamically load data from the server? Using Angular controller and params with requests: app.controller("MyCtrl", function($scope) { ...

How can the vertical scroll bar position be reset in Material-Table when pagination is activated?

Whenever I scroll up or down in my Material-Table, and then switch pages, the vertical scroll bar doesn't reset to the top of the table. Instead, it stays where it was before changing the page, causing confusion for users. The only mention of scroll ...

Enhance your JavaScript code by replacing Promise syntax with Async syntax and utilizing map() instead of a traditional For

I have a code snippet here that is functioning properly. However, I am interested in converting the Promise code in the middle of the function to Async code and replacing the for loop with map(). Can someone guide me on how to achieve this transformation ...

Challenges encountered with the "load" event handler when creating a Firefox Extension

I am currently troubleshooting a user interaction issue with my Firefox extension. The tasks that my extension needs to complete include: Checking certain structures on the currently viewed browser tab Making backend server calls Opening dialogs Redirect ...

While Ajax POST is functional on desktop, it does not seem to work on Phonegap applications or Android

I am facing an issue with a global function that does not seem to work properly in the PhoneGap Desktop app or Chrome Mobile on Android. Surprisingly, it works perfectly fine only in the Chrome PC version. The function is called using an onClick event, a ...

Retrieving specific data from nested arrays in Vue.js

I am currently working on Vue.js template development and facing an issue with filtering nested data in a faq section. When I try to add a search bar, the nested data array returns all data without proper filtering. Dom <v-container> <v ...

Setting up user roles using Firebase Auth in NextJS application

Seeking a solution to implement a multi-level role system for my blog website. Currently utilizing Firebase Auth for authentication with email/password, but all users have the same posting/editing access. Looking to differentiate between Admins, Moderators ...

Having trouble finding the element during Selenium JavaScript testing

I need help testing a JavaScript script using Selenium, but I am running into an issue. I cannot seem to find a specific element that I want to click on. Here is a snippet of my JS code where I am trying to click on the Shipping option. I have tried us ...

Using the DatePicker component with non-escaped Latin alphabet characters in date-fns for ReactJS

While attempting to integrate the DatePicker component from Material UI into my React project, I encountered an error. Although many attributed the issue to a version discrepancy, what ultimately resolved the problem for me was assigning a value to the Da ...

Auto Suggest: How can I display all the attributes from a JSON object in the options list using material-ui (@mui) and emphasize the corresponding text in the selected option?

Currently, I am facing a requirement where I need to display both the name and email address in the options list. However, at the moment, I am only able to render one parameter. How can I modify my code to render all the options with both name and email? ...

Can a variable be declared within the path references of the Firebase database?

In an effort to update my app's database references, I am working on implementing specific Firebase rules that involve adding buildings and depts nodes inside the user node. This decision was prompted by a discussion on best practices for writing Fire ...

Livereload in Gulp fails to automatically restart the server

How can I make my gulp+livereload server automatically restart and update the page when JS files are changed? Below is a snippet from my gulpfile.js: var gulp = require('gulp'), livereload = require('gulp-livereload'), ...

Create a time of 00:19:59 using JavaScript

I am attempting to display a countdown timer that starts at 20 minutes in the format (00:20:00) using setInterval. Once the countdown is finished, it should display as (00:00:00), but I am having trouble achieving this. <body onload = "onloadFunc();" ...