GithubHelp home page GithubHelp logo

drag-drop-touch-js / dragdroptouch Goto Github PK

View Code? Open in Web Editor NEW
462.0 462.0 124.0 164 KB

Polyfill that enables HTML5 drag drop support on mobile (touch) devices.

License: MIT License

JavaScript 30.50% TypeScript 60.81% CSS 1.66% HTML 7.03%

dragdroptouch's People

Contributors

alexmontdor avatar bernardo-castilho avatar desaroll avatar dpitois avatar elbotija avatar elbywan avatar mburger81 avatar moniikag avatar ndp avatar pomax avatar rozek avatar zfrhv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dragdroptouch's Issues

Drag-Drop-Touch-Polyfill not working with React Grid Layout library

Hello Sir,
I am trying to make the react grid layout library work in mobile resolution using drag-drop-touch-polyfill but it does not seem to work out. Getting the "Maximum update depth exceeded" error while dragging the element.

Have attached the code sandbox link below for reference:-
https://codesandbox.io/s/react-grid-layout-nested-grids-drag-from-outside-forked-rvg1ph?file=/DragDropTouch.js

I request you to please look into the issue. It will be great if you can help me out.

Thanks in advance!

FR: support of shadowdom

We are creating a web component for drag and drop with stenciljs and your mobile lib.

we give the ability to add a custom drag image, it is working on NON mobile behavior but it is not working on mobile, because you don't support shadow dom.

But stenciljs is realing on web components with shadow dom and css4 variables.

Can you help?
The main problem is the default src.cloneNode(true) is not coping slots and nested custom elements.

Some ideas how we can resolve this?

Not sure if deep cloning on shadowdom is working. One solution could be passing an element to your lib and your lib does not adding this to the dom, but it moves only the given element instead of the cloned element

Scrolling when not touchhold for some time

Is there anyway to allow scrolling when you haven't press and hold a draggable element for say 1000 ms? right now if I try to swipe on an element that is draggable, it just won't do anything.

No 'drag' event listener

Thanks for the great package.

I noticed it was not detecting the 'drag' event, which I am using for my own functionality instead of 'dragenter', 'dragleave', 'dragover', or 'drop'. Since I am not using those other events I changed the code in DragDropTouch.js to dispatch 'drag' event on touchmove and ignore if (target != this._lastTarget) because I am simply handling it using screen positioning.

I also had to make a minor change in my code since the 'drag' event has event.offsetX but this new touchmove dispatch did not. I just updated my code like so if (e.offsetX === undefined && e.clientX) offsetX = e.clientX; and it works perfectly.

Anyway, it would be nice if this just worked in case people need to use that event in addition to detecting when the drop target has changed. I am using jquery and only have three events: $("#myElement").on("dragstart", ...) , $("#myElement").on("drag", ...) , and $("#myElement").on("dragend", ...)

Chrome warnings about preventDefault of passive targets

Hello and thank you for this polyfill. It's exactly what we've been looking for. There's just one small issue:
Chrome (probably starting at version 56) seems to not be happy about the preventDefault-calls as it treats the touch-listeners as passive. This does not seem to interfere with the functionality, but for a simple drag-process, ~100 of these warnings are logged to the console:
[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080
I fear that this may also be discouraged for mobile browsers and may become unsupported in the future, so I thought I'd give you a heads-up.

Drop is always alowed

We try to use your dragdroptouch polyfill to write a new web component with stenciljs for drag and drop.

Your polyfill is working great but we found one issue. In standard browser behavior the dropping is only allowed if ondragover event does an ev.preventDefault()

But in your case your _touchend performs always an drop event. I created a PR for this #23

How to use Drag Drop Touch in Angular 10

Dear Sir,
After taking a look at DragDropTouch polyfill demo, it seems to me it has been designed for AngularJS with Wijmo Licensing .... I just wonder how to use your library DragDropTouch polyfill for my web app that use Angular 10 though.

Furthermore, I have found that without Wijmo Licensing, I cannot simulate the drag drop using responsive simulation of mobile devices (I-pad, I-phone, Galaxy note, Galaxy mobile or so).

Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.

Hey,

I've been trying to implement dragdroptouch in a small project. It's a game of Mastermind, written in html and vanilla Javascript.

It works as expected on desktop browsers, but only partly on Android (haven't tested iOS).

That is to say, I can drag, but not drop.
When I drop an item, I get the error in the subject line, and can trace it to lines 378 and 250 in DragDropTouch.js

The game/source can be found here: http://world.is/games/mastermind/

Any help would be highly appreciated.

-DJ-

Suddenly exception in MS Edge: "Unable to get property 'handleEvent' of undefined or null reference"

It used to work in Microsoft Edge now I'm getting "SCRIPT5007: Unable to get property 'handleEvent' of undefined or null reference" in DragDropTouch.js (143,13):

document.addEventListener('test', null, {
    get passive() {
        supportsPassive = true;
        return true;
    }
});

This is Edge 40.15063.0 (EdgeHTML 15.15063). Looks like a real browser bug as handleEvent is mentioned nowhere in the code and from what read from other people seeing this problem in other libraries. At a quick glance I also couldn't find any obvious workarounds.

Failed to minify react-scripts build

Have you planned to fix this error?
It would be nice for the future of this npm package!

the error:

npm run build fails to minify
Some third-party packages don't compile their code to ES5 before publishing to npm. This often causes problems in the ecosystem because neither browsers (except for most modern versions) nor some tools currently support all ES6 features. We recommend to publish code on npm as ES5 at least for a few more years.

To resolve this:

  1. Open an issue on the dependency's issue tracker and ask that the package be published pre-compiled.
  • Note: Create React App can consume both CommonJS and ES modules. For Node.js compatibility, it is recommended that the main entry point is CommonJS. However, they can optionally provide an ES module entry point with the module field in package.json. Note that even if a library provides an ES Modules version, it should still precompile other ES6 features to ES5 if it intends to support older browsers.
  1. Fork the package and publish a corrected version yourself.

  2. If the dependency is small enough, copy it to your src/ folder and treat it as application code.

In the future, we might start automatically compiling incompatible third-party modules, but it is not currently supported. This approach would also slow down the production builds.

Add support for Shadow DOM

Dear Sir,
I'm wondering if you could add support for Shadow DOM to this polyfill. I've been testing it with Lit and have found that any elements in a Shadow DOM on a mobile screen do not have any of the drags events fired, and are just not draggable in general. Here's a demonstration. (It doesn't use Lit, but it uses Shadow DOM.)

Sincerely,
Andrew

Input field in draggable element doesn't work on mobile

Thank you so much for an amazing and much-needed fix! I'm so grateful. I hope that the issue I'm raising here is helpful for further development.

An issue I've encountered is that I have an field in one of my draggable elements (which users need to be able to add text to), and currently on mobile it is not possible to edit the field. Do you have a suggestion for a workaround?

To see what I mean, go to communityrule.info/create, click the wrench-shaped button, and see the "Custom..." module that appears. Try to edit the field.

Thank you so much for considering this, and let me know if I can provide any further information.

Support for pointer events

There's this new standard for handling pointer events, that aims to unify work across all devices and types of pointer interfaces (mouse, touch, stylus, etc.): https://www.w3.org/TR/pointerevents/

It would be good for this library to support it. However, it is not yet supported in Safari, both desktop and mobile: http://caniuse.com/#search=pointer%20events. However, the motivation for supporting these events instead is because the touch events are not supported in IE-11/Edge on Microsoft Windows touch devices.

I was even meaning to start a pull-request of this repo and contribute this change myself, but given the lack of support of this feature in Apple devices, I decided to first ask here what do you think would be the best approach, or even if it's worth it. Perhaps I could attempt to detect if the browser supports pointer events, and use that, or else use touch events as it is today. What do you think?

NPM package outdated

First, thanks for this polyfill, it's been a lifesaver :)

We have been using the NPM package on my project to get drag interactions working on Safari, and recently we ran into problems with touch events on Chrome (ChromeOS/Windows).

I spent a bit of time debugging and when I was about to propose a PR with a fix, I found out that it has already be fixed in this commit: 63e4a9a, but the update never made it to NPM. The latest version (1.3.1) precedes this update.

If you could publish the latest updates to NPM, this would benefit a lot of users who have relying on the NPM package. Thanks again for the great work.

Script breaks with this code


<script>
--
  | function allowDrop(ev) {
  | ev.preventDefault();
  | }
  |  
  | function drag(ev) {
  | ev.dataTransfer.setData("text", ev.target.id);
  | }
  |  
  | function drop(ev) {
  | ev.preventDefault();
  | var data = ev.dataTransfer.getData("text");
  | var nodeCopy = document.getElementById(data).cloneNode(true);
  | //nodeCopy.id = "newId";   // If this line uncommented, it does not work on desktop but if commented out this works on desktop. neither work on mobile.
  | nodeCopy.setAttribute('draggable', false);
  | nodeCopy.setAttribute('height','2px');
  | ev.target.appendChild(nodeCopy);
  |  
  | }
  | </script>



How to drag&drop from window A to window B in Android?

i tried to use dragdroptouch to drag a thumbnail across windows (which is doable with mouse), but it doesn't work (drag&drop within the same webpage works fine). is it a limitation of html5 drag&drop api? if not, is it possible to add this feature to dragdroptouch? coz it would be super useful, to me at least.

you may now publish your module as an NPM package

Hello Bernardo,

your merge was really fast! Thanks a lot!

Now, that you have a package.json, you may also publish your module as an NPM package.

There IS already such a publication called drag-drop-touch - but, it seems to have been prepared by somebody else (although I don't know by whom). That publication also lacks any reference to this Github repo and to the ReadMe file.

Nevertheless, that package is extremely popular (more than 1000 downloads/week)

I have no idea whether you are allowed to overwrite the package with your new version. If so, you should apply the following changes to package.json

  • change the name to drag-drop-touch
  • change the version to s.th. higher than 1.3.1

npm publish will then publish your module

Alternatively, you may publish your code with the package.json I provided to you (name dragdroptouch, version 1.0.0)

If you like, I may also provide the package.json I described before.

With greetings from Germany,

Andreas Rozek

Deteting touch screen on laptop

The polyfill works fine in Phones and tablets. It's Great!

But there is an issue with laptop with touch screen devices.

I suggest modifying this section:

            // listen to touch events
            if ('ontouchstart' in document) { // <- problem with laptop touch screen 
                var d = document, ts = this._touchstart.bind(this), tm = this._touchmove.bind(this), te = this._touchend.bind(this), opt = supportsPassive ? { passive: false, capture: false } : false;
                d.addEventListener('touchstart', ts, opt);
                d.addEventListener('touchmove', tm, opt);
                d.addEventListener('touchend', te);
                d.addEventListener('touchcancel', te);
            }

and change it like this:

            // listen to touch events
            if (navigator.maxTouchPoints) { // <- better way to detect touch screen
                var d = document, ts = this._touchstart.bind(this), tm = this._touchmove.bind(this), te = this._touchend.bind(this), opt = supportsPassive ? { passive: false, capture: false } : false;
                d.addEventListener('touchstart', ts, opt);
                d.addEventListener('touchmove', tm, opt);
                d.addEventListener('touchend', te);
                d.addEventListener('touchcancel', te);
            }

Drag doesn't work when page is longer and needs to be scrolled.

Hello,
First of all thanks for taking your time to publish this drag and drop.
I have a problem with it if the page has scroll (is bigger than the demo page) on iOS. (tested on iphone se)
Any idea how to fix this issue?
Also is it possible to scroll while dragging like on desktop?

Thanks,
ukw.

Demo doesn't seem to work with Chrome devices panel

The demo doesn't work with Chrome devices panel, when switching to a mobile device.

Steps to reproduce:

  1. Load the page in Desktop mode.
  2. Open developer tools.
  3. toggle device to any mobile device.
  4. The touch based drag and drop events do not work anymore.

I suspect this might be related to switching devices after the page is loaded, as on a new page reload with mobile device selected, it seems to work fine.

It also works fine on my mobile chrome.

Desktop Chrome version: 79

Enabling the polyfill only when draggable attribute is set

Hi, thanks for the PKG.

The line here seems to have changed to make default draggable attributes also draggable on mobile:

https://github.com/Bernardo-Castilho/dragdroptouch/blob/415fcf577d39bfac042d9215a02660d5c1df2f10/DragDropTouch.js#L453

However I'd suggest a toggle to change this behavior back to the old one, because making these elements draggable by default (like a and img) disables scrolling when you start scrolling from those elements, at least on iOS Safari and Android Chrome. The workaround seems to be to set draggable to false on every attribute but that would be a bigger hassle than just re-enabling that line or having that line be toggleable.

Contributing changes

Heya,

I was trying to use this library and ended up forking it and "massaging" it a little, possibly more than you'd like, maybe exactly as much as you'd wish you had time to do, so: I have a fork up over on https://github.com/Pomax/dragdroptouch that I wouldn't mind filing as an upstream contribution if you think that's a good idea.

Some of the major changes include:

  • it has a build system now (using esbuild), compiling a drag-drop-touch.esm.js and drag-drop-touch.esm.min.js.
  • on that note, it compiles an ESM file, because it's 2024 and I want to be part of the solution =D
  • the demo page got leaned up, maybe too much for your liking, but as a random drive-by user I have no interesting in wijmo, so the only example that still exists is the box example because if that works, anything works.
  • it looks for an "autoload" parameter (when loaded on its own), which just immediately builds a singleton instance so that "things just work(tm)" rather than someone needing to still call new DragDropTouch().
  • I removed the "supportsPassive" check because it's 2024 and everything does =)
  • I replaced a few loops with different/more modern loops
  • There is a piece of code that had // Added by NDP OK? TODO and reading over it, it wasn't OK in that it first returned if some condition was false, then followed that up with an if statement that could never be true. So that got changed.

Let me know what you'd like me to do here (happy to just keep it a fork, but even happier to get everything landed upstream of course =D).

(there is one wonky bit, where touch-dragging the box with an image doesn't do quite the right thing, but that's something that should be relatively "easy" to fix as part of the upstreaming)

the element is still draggable even if I set "draggable" attribute as false

My intention was to make

element draggable after holding finger for certain time.

option1.

----- from html ------
div class="boxA" draggable="false"

----- from javascript ------
["boxA" element].addEventListener('touchscreen', function () {

setTimeout(function() {
  ["boxA" element].setAttribute('draggable', true);
}, 2500);

});

but it seems like I can drag the "boxA" div without any delay (hence ignoring draggble "false" value).

I tried another way by removing draggable attribution from html and add it from javascript but it wouldnt allow me to drag

option2.

----- from html ------
div class="boxA"

----- from javascript ------
["boxA" element].addEventListener('touchscreen', function () {

setTimeout(function() {
  ["boxA" element].setAttribute('draggable', true);
}, 2500);

});

is there any way to temporarily disable drag & drop feature on mobile screen?

Help excluding draggable elements.

I implemented the simple ability to initiate toggling a sidebar with DragDropTouch.js and it works great and was exceedingly simple to implement. Many thanks for this excellent polyfill.

I made an attempt to limit the effects of this script to elements that have a "touchdraggable" attribute, which I set in addition to the draggable attribute on elements that I want touchdraggable. I changed the element selector clause in DragDropTouch.prototype._closestDraggable at current line 422 to be:

if (e.hasAttribute('draggable') && e.draggable && e.hasAttribute('touchdraggable'))

It seems to work on an element I have defined draggable but not touchdraggable. Touch events no longer trigger on this element as I intended. The problem I'm having is with the map (Mapbox) on the page. Even though there are no "touchdraggable" attributes on any map element the touch map controls are altered when this polyfill is loaded.

So I'm wondering if there's any way to fully exclude the map element touch events from being altered/ influenced by this polyfill? TIA

Support for FlexGrid Range Selection using Touch Gestures

It would be nice if the user could touch-and-drag to select a range of cells or rows in the FlexGrid. But this gesture doesn't work for your demo on my Windows 10 all-in-one touchscreen machine using either Chrome or Edge. Also it would be nice to support disjoint row-selections using touch gestures for the ListBox selection mode.

Image is not draggable on Canvas.

I am using Fabric.js for my Image Editing App based on Angular 15.

My html draggable="true" is not working on mobile Screens. I found your polyfill. after adding it i am able to drag my images but its not going onto Canvas. Dragging stops when my touch reaches to canvas element. apart from canvas element i can drag my image anywhere.

Cleaning up "draggable"

Hi Bernardo, nice work!

I have one issue:
If you go to: http://sslweb.azurewebsites.net/

  1. click the bottom left icon (sort)
  2. drag and drop a list-item to manually sort the list
  3. click again the bottom left icon to disable sorting

Result on phones (tested on android and windows phone)

  • still possible to drag an item
  • scrolling on the list is broken

I guess there is something wrong with the event cleanup. In the list you can find items like
<div class="win-itembox" draggable="true">. The draggable attribute will be removed by clicking the 'disable sorting' icon.

How can I access the 'DragDropTouch' object on the '.win-itembox' element to do some cleanup?

Best Regards,
George

Internal selections is not working

Hello! I'm just a newer in js, your code very helpful.
In my case, the internal selections stop working, but drag and drop finally working correctly.
Where is can be an issue?
[image deleted]

Drag event was throwing only while on the element I was dragging

The 'drag' event was being sent only on the element I was dragging, and no while draggin throught the whole screen.

I fixed that by chaging lines 222 to 234 to:

              if (this._img) {
                    this._lastTouch = e;
                   //e.preventDefault(); // I commented this out 
                    if (target != this._lastTarget) {
                        this._dispatchEvent(this._lastTouch, 'dragleave', this._lastTarget);
                        this._dispatchEvent(e, 'dragenter', target);
                        this._lastTarget = target;
                    }
                    this._moveImage(e);
                    this._dispatchEvent(e, 'dragover', target);

                    this._dispatchEvent(e, 'drag', e.target); // I changed here to use the e.target
                }

Now it works!

Drop event does not seem to fire

First of all, many thanks for this wonderful polyfill. I am new to web development, and was quite frustrated to find that the Drag and Drop API is not supported on mobile devices.

However, in my application, the drop event still does not seem to work on mobile devices. I suspect this has to do with the dragover event. In many Drag and Drop-based applications, the dragover event has to be cancelled (using e.preventDefault()) in order for the drop event to fire, since the dragover content continuously fires when the dragged element is above the target. Unfortunately, the DragDropTouch script apparently relies on the dragover event to detect the current drop zone:

//Taken from line 241 (the touchmove method setup)
// The dragover event is required to identify the drop zone
this._isDropZone = this._dispatchEvent(e, "dragover", target);

This seems to produce a dilemma, since the DragDropTouch script does not recognise the drop zone if the default dragover event is prevented, but the drop event does not fire if it is.

In my current application, the drop event is rather important, as certain animations are played on drop, and certain properties of the dragged element and the drop target are compared on drop. Like I said, I am new to web development, so I have not been able to find a way to either bypass the drop event entirely in my own script or alter the DragDropTouch script in such a way that it does not depend on the dragover event.

dblclick event triggered twice on touch screens

Using this library makes the dblclick event to be triggered two times on touch screens. Here is a demo https://jsfiddle.net/ouLzd13f/.

The library states that it will:

Raise the dblclick event when there's a new touchstart right after a click

But newer browsers handle the dblclick event natively so this makes the event dispatch twice.

Many thanks !

Hi Bernardo,

I struggled for a while to make my desktop drag&drop code to work for touch screens. I tried all sorts and other polyfills to no avail. I added yours as a one liner to the JS in the html, and it worked straight out of the box.
Big, big thank you for this, very nice work.

Cheers,
Jesus
PS: this is where I used it for | https://soundspinning.github.io/Puzzles/puzzle-Chloe.html

Does not work on windows-based touchscreen

Hi,

unfortunately your awesome polyfill does not work on windows touchscreens. I seem to remember that it worked in the past, but at the moment (Win 10 21H1) not.

In firefox browser, a preceding double-tap on the draggable element makes the dragging work, in chrome / edge this trick doesn't do anything.

Any idea how this can be fixed?

Images are draggable by default

But that doesn't work with this polyfill unless you set the draggable property explicitly.

Same applies to anchors, so presumably those are also broken.

Cannot scroll over dragable content

I've been developing a dragable table for mobile devices. I found that this js does not work as expected in some devices(Ipod, Ipad, Iphone 5,6,6+, android < lollipop). The issue im having is that one cannot scroll the device over the content defined as dragable.
To fix this issue i have added a small delay in the _touchstart function

Demo page doesn't work, and uses a "dead" copy of wijmo

The polyfill doesn't, from what I can tell, rely on any specific framework, so having the demo page use an unlicensed, out-of-evaluation-period page framework actively harms the "have a look at how well this works" aspect of this polyfill =)

Especially because the demo page doesn't work: I can't tell if this polyfill is broken, or whether wijmo is breaking it because there's no license to use it, but either way touch events just scroll the page instead of moving elements around.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.