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

Selecting an option from the knockout dropdown menu

I implemented a language dropdown in layout.chtml using knockout js. <select id="Language" class="styled-select" data-bind="value: Language,options: locale, value: selectedLocale, optionsText: 'name'"></select> var viewModel = th ...

Getting rid of the standard border around images

I've been searching for a while now, but I can't seem to find a solution to fix this specific issue. On a webpage, I have an image (<img...>) that, when it loads, shows a 1px solid white (or very light grey) outline or border on the outermo ...

Creating characters dynamically based on the length of user input in VSCode Snippet

Here is a simple vue-html snippet: { "BANNER1": { "prefix": "banner", "body": ["<!-- ----------------", "/// $1", "--------------------- -->"] } } This sni ...

Ways to obtain the latitudes and longitudes for various routes between a starting point and a destination

At the moment, I am successfully retrieving all the latitude and longitude coordinates from the source to destination location. However, I am only able to obtain 1 path using this method. Now, I would like to have the ability to choose a specific route p ...

Angular - Detecting Scroll Events on Page Scrolling Only

I am currently working on implementing a "show more" feature and need to monitor the scroll event for this purpose. The code I am using is: window.addEventListener('scroll', this.scroll, true); Here is the scroll function: scroll = (event: any) ...

The addEventListener method fails to respond to changes in input

Can someone assist me with this issue? I am facing a problem where the input.addeventlistener is not detecting files on change. My setup involves using Vue with Rails. I am looking to trigger the event listener in the mount hook of a Vue component. mo ...

The combination of Angular Hottowel's 'blocks.exception' and 'blocks.router' prevents the App from being displayed in the browser

After delving into Angular's fundamentals a couple of months back, I am now venturing into building a practice app that mirrors industry standards. I recently completed John Papa's Play by Play and Clean Code courses on Pluralsight, which furthe ...

Bottom-aligned footer that remains in place instead of sticking to the page

I am attempting to position a footer at the bottom of the page, without it being sticky. Instead, I want it to remain at the bottom in case the user scrolls down there. Although it technically "works," there appears to be some white space below the footer ...

Symfony2 compresses CSS and JS files to improve performance

Currently, I am attempting to execute php app/console assetic:dump in order to test my production environment. While my css file gets generated successfully, the js file does not. The following error message is displayed : C:\wamp\www\p ...

Issue encountered while attempting to write KML objects to Google Earth API: NPObject error

Currently, I am working on a script that aims to extract data from Facebook and display it graphically on a Google Map using simple extruded polygons. The social integration and AJAX functionality are both working fine for me. However, whenever I try to ex ...

Using CSS to leverage the power of both Grid and Flex simultaneously

Help Needed: CSS Challenge! I'm not a fan of CSS and can't seem to crack this code conundrum. Here's what I want the end result to look like: Current Situation: #newOrderControl { border-style: solid; border-color: black; b ...

Tips for customizing the appearance of a single plot within a time series chart using FusionCharts or FusionTime

I've implemented a time series line graph using FusionCharts in the following code snippet: const MyChart = () => { const schema = [ { name: "Category", type: "string" }, { ...

Combining round brackets and square brackets when initializing an array

In the snippet below, values are assigned with a mix of parentheses and square brackets without any errors. However, most other combinations (such as parentheses inside square brackets) do not work at all. var myItems = []; myItems[5] = ("A1", "B1", ["C1" ...

The logout feature might refresh the page, yet the user remains logged in

Currently, I am enrolled in a course on Udemy where the instructor is utilizing Angular 2. My task involves building the app using the latest version of Angular. The issue that I am facing pertains to the logout functionality. After successfully logging ou ...

Troubleshooting the Issue of Angular Model Not Refreshing in Angular.js

Running into an issue with my directive where the model isn't updating as expected. Here's a snippet of my HTML code: <div class="text-area-container"> <textarea ng-model="chatText" ng-keyup="updateCount(chatText)">< ...

Tips for animating the box-shadow effect using jQuery

Can anyone provide insight on how to animate the box-shadow of multiple elements? I have reviewed previous threads such as this one, but found outdated and non-working solutions. Additionally, I came across the jquery box-animation plugin, which is limit ...

Image pop-ups that overlay text on the homepage

I'm facing an issue and I'm looking for a solution... Upon entering my homepage, I would like to display a popup image showcasing a new event so visitors can see it before accessing the website. I attempted to achieve this using JavaScript but w ...

From converting jQuery nav-scroll to a directive in AngularJS: the power of directives

I'm struggling to convert my jQuery code into a pure AngularJS directive. I thought it should work, but I've only created one directive before. Could someone please point out what I might be doing wrong? The directive doesn't seem to have a ...

Can a javascript code for "Infinite Scroll" be created to manage the back button?

Head over to this website: Experiment with the infinite scroll feature. You may notice that when you click a link and then press "back", there are some glitches. Therefore, I am considering developing my own version of an Infinite Scroll functionality. ...

Extract reference value from an HTML element

Is there a way to access the ref prop from an HTML element using Testing Library React? My current code snippet is as follows: it('element container ref should be null if prop noSwipe is passed', () => { const onCloseMock = jest.fn() ...