JavaScript drag functionality is jerky on iPads, not seamless

I am currently attempting to implement a feature where I can drag a div (#drag) within its parent container (#container) using only pure JavaScript. This functionality is specifically required to work on iPad devices only.

After writing a script that functions perfectly when testing in Chrome with touch events emulation turned on, I encountered an issue on an actual iPad. When dragging the div too quickly, it no longer follows my finger.

My initial thought was that my finger might be moving out of the element too fast, so I tried setting the addEventListener on the body instead of the div, but unfortunately, the problem persisted.

If anyone has any insights into why this issue is occurring and how it can be resolved to ensure smooth functionality on iPads, I would greatly appreciate your input.

Demo: http://jsfiddle.net/kxrEZ/

Javascript:

var dom = {
    container: document.getElementById("container"),
    drag: document.getElementById("drag"),
}
var container = {
    x: dom.container.getBoundingClientRect().left,
    y: dom.container.getBoundingClientRect().top,
    w: dom.container.getBoundingClientRect().width,
    h: dom.container.getBoundingClientRect().height
}
var drag = {
    w: dom.drag.offsetWidth,
    h: dom.drag.offsetHeight
}

target = null;

document.body.addEventListener('touchstart', handleTouchStart, false);
document.body.addEventListener('touchmove', handleTouchMove, false);
document.body.addEventListener('touchend', handleTouchEnd, false);

function handleTouchStart(e) {
    if (e.touches.length == 1) {
        var touch = e.touches[0];
        target = touch.target;
    }
}
function handleTouchMove(e) {
    if (e.touches.length == 1) {
        if(target ===  dom.drag) {
            moveDrag(e);
        }
    }
}
function handleTouchEnd(e) {
    if (e.touches.length == 0) { // User just took last finger off screen
        target = null;
    }
}

function moveDrag(e) {
    var touch = e.touches[0];
    var posX = touch.pageX - container.x - drag.w / 2;
    var minX = 0;
    var maxX = container.w - drag.w;
    if(posX < minX) {posX = minX;} 
    else if(posX > maxX) {posX = maxX;}
    var posY = touch.pageY - container.y - drag.h / 2;
    var minY = 0;
    var maxY = container.h - drag.h;
    if(posY < minY) {posY = minY;} 
    else if(posY > maxY) {posY = maxY;}
    dom.drag.style.left = posX + "px";
    dom.drag.style.top = posY + "px";
}

Answer №1

To optimize the performance of your code, consider storing frequently used variables in a static memory pool instead of re-declaring them every time moveDrag is called. This can help reduce overhead since the function is invoked multiple times. Additionally, avoid updating offset values using style.left and style.top dynamically during each touch event, as it triggers reflows. Instead, utilize render transforms for smooth movement and update styles only in handleTouchEnd.

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

Modal's ng-click not triggering component's function

I am currently working on resolving an issue. My choice to use AngularJS is intentional, as I prefer not to load the entire NPM of Angular. Additionally, we heavily rely on Razor Syntax for the Web Layer. Implementation in Create.cshtml file <button ...

Attempting to move elements into an array for storage in the local storage

Is there a way to properly add elements to an array and store it in localstorage? Here's the code snippet I've been working with: const handleSelectLayouts = (layout) => { const layoutsArray = []; layoutsArray.includes(layout) ...

Accessing the current clicked item in $scope using an Angular Directive within ng-repeat

I have set up a custom directive called calendar which includes a date picker created in JQuery. To associate the ng-model with the date picker, I am using the following code successfully: var clickedID = "#" + $scope.indexid + "_datePicker"; $(clickedID ...

Validation for dates in Angular.Js input is important to ensure that only

Take a look at this form: <form name="user_submission" novalidate="novalidate" method="post"> <input type="date" name="date_of_birth" ng-focus="save_data()" ng-model-options="{timezone: 'UTC'}" ng-pattern="/^(19\d{2}|[2-9]& ...

Adjust the position of the IMG to the left side

Struggling with some code and need some assistance: <script> function run() { document.getElementById("srt").value = document.getElementById("Ultra").value; } </script> <script> function ru ...

Controlling File Upload Edits: A Guide to Effective Management

I am facing an issue on my product page related to adding and updating products in the database. The problem lies with images not displaying correctly. During the product insertion process, everything works fine. In my aspx page, I have the following code ...

Ways to Insert Text and Values into an Array

{{ "user": "randomuser", "message": "require assistance" }, { "user": "automated assistant", "message": "do you need any help?" }, { "user": "randomuser", "message": "another inquiry" } I am seeking to extract additional paragraphs ...

In Javascript, we can increment the current date by utilizing the `getDate()`

I am trying to create an if statement in JavaScript; if (nextProcessingDate > today ) { //do something } nextProcessingDate has a timestamp assigned, like 09/07/2014 12:10:17 To assign today's timestamp to the today variable, I am using this c ...

Is it possible to verify the versions of node and npm prior to running an npm install command?

To ensure only specific versions of node and npm are used before a user can run the npm install command on my module, I need to set certain criteria. According to NPM documentation, I can use the engine attribute for this purpose: "engines": { "nod ...

The SSE emitter sends out multiple signals, but occasionally the browser fails to receive them

When setting up an event emitter in a node.js/express application, I noticed that the events emitted are sometimes received multiple times by the front-end listener. Although I can confirm that emit is only called once, the same event gets emitted up to 4 ...

Encountering a 404 error in Angular MVC project while trying to load a

Trying to access an edit partial named AddEditPersonModal.cshtml from a different folder in my MVC project, in order to load its contents into a UI Bootstrap modal using Angular. However, when the index.cshtml page loads, I encounter a 404 error related to ...

What are the steps to perform an Ajax request to an online web service?

I would like to send an AJAX request to an external web service using jQuery. However, I am encountering an error and unable to receive a successful response from the server. var url = "http://www.example.com/api/convert"; var requestData = { temperat ...

My navigation menu has a nested ul, but on mobile devices, it doesn't display all the items in the list. What could be causing

When I click on "Products" in my main navigation, only the first 6 items are displayed from a nested ul. How can I make all of them display when the user clicks on "Products"? Is this a CSS issue or a problem with the script? Here's a screenshot for r ...

Choose a phrase that commences with the term "javascript"

I need assistance in creating two unique regular expressions for the following purposes: To select lines that begin with 'religion'. Unfortunately, my attempt with /^religion/g did not yield any results. To match dates and their correspondi ...

Is it possible to locate both the child and parent elements by their class names simultaneously using WebDriver?

When conducting a search on eBay that returns more than 50 listings, such as this example, the site displays the results in either grid or list format. Using the WebDriver tool, I am extracting prices by their class name: https://i.stack.imgur.com/dGNzw. ...

The animation speed of the jQuery hashchange event is set to zero, causing the animation

I'm facing an issue with jQuery where my animation inside a hashchange event is not smooth; it happens instantly when triggered. I'm looking for a way to make the animation smoother. jQuery( document ).ready(function() { jQuery(window).on(&a ...

Import reactjs modules without the need for Browserify, Webpack, or Babel

I am attempting to set up a TypeScript HTML application in Visual Studio. My goal is to incorporate reactjs v0.14.7 without relying on tools like Browserify. But, how can I utilize the react-dom module in this scenario? Let's set aside TypeScript fo ...

Excerpts capturing the significance of HTML attribute values

$(document).ready(function () { for (var n = 0; n < 3 ; n++) { $("body").append("<p id=\"element"+n+"\">Greetings, I am Element " + n + ".<p>"); } }); In the third line of code, which pairs of quotation marks match ...

The angular controller function is failing to set $scope.value

I've been facing an issue with setting an Angular variable value in a controller function that is created by a directive. For some reason, it doesn't seem to work when I try to assign the value within the controller function, even though it displ ...

The majority of my next.js website's content being indexed by Google consists of JSON and Javascript files

I’m facing an issue with Google indexing on Next.js (utilizing SSR). The challenge lies in ensuring that .HTML files are effectively indexed for SEO purposes. However, it seems that Googlebot predominantly indexes JSON and JavaScript files. To illustra ...