drag-drop-touch-js / dragdroptouch Goto Github PK
View Code? Open in Web Editor NEWPolyfill that enables HTML5 drag drop support on mobile (touch) devices.
License: MIT License
Polyfill that enables HTML5 drag drop support on mobile (touch) devices.
License: MIT License
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!
When I see your demo and open console , I can see the typeerror at DragDropTouch.js:317, what's wrong with this? but the demo can still drag and drop even though there is an error....
By using this polyfill, the browser detects keypresses even when dragging (which is not a thing with a native html5 drag and drop). Is this possible to make this polyfill function in desktop browser?
When running the demo, I get the following error in the console.
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.4.5/$injector/modulerr?p0=app&…ax%2Flibs%2Fangularjs%2F1.4.5%2Fangular.min.js%3A292%3A64%0A
I get a similar error when integrating DragDropTouch in my own project. Any ideas?
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
i want to use this file in my reactjs app, how can i import and run it?
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.
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", ...)
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.
In my case, I'm using a translate transform style and the drag image is way offscreen. My workaround is to add this._img.style.transform = 'none';
in the same place where left
and top
are set to -9999. I'm not sure if this has other unwanted side effects though, but it works in my use case,
It looks like the demo link is not currently being served from the master branch - I do not have settings access, @Bernardo-Castilho could you double check that the "pages" section in settings points to the master branch's root directory?
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
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).
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-
I've looked all over and can't find an answer to this. I'm using angular 5.
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.
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:
Fork the package and publish a corrected version yourself.
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.
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
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.
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?
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.
This appears to have slipped through code review. Surely this is not the intended behaviour?
(It tries to install a browser when installing the package; in my case it failed.)
<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>
Is there an easy way to get it to scroll the page/div while dragging on Android Chrome? My drop target may be down at the end of a long div that would require scrolling while dragging.
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.
From https://github.com/Bernardo-Castilho/dragdroptouch/blob/master/LICENSE
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
Would that also apply to the minimized version?
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
name
to drag-drop-touch
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
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);
}
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.
The demo doesn't work with Chrome devices panel, when switching to a mobile device.
Steps to reproduce:
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
Somehow this Polyfill breaks Bootstrap 3 dropdown submenu functionality on mobile devices: freescout-help-desk/freescout#3708
Tiny issue: DragDropTouch.js references a SourceMap-file, DragDropTouchNoWijmo.js.map that does not exist (at least not in the releases):
https://github.com/Bernardo-Castilho/dragdroptouch/blob/master/DragDropTouch.js#L408
Hi, thanks for the PKG.
The line here seems to have changed to make default draggable attributes also draggable on mobile:
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.
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:
drag-drop-touch.esm.js
and drag-drop-touch.esm.min.js
.new DragDropTouch()
.// 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)
My intention was to make
----- 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
----- 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?
with 2.0.0 landed in terms of code, it would be good to spin a v2.0.0 tag and update https://www.npmjs.com/package/drag-drop-touch - @Bernardo-Castilho I see a v1.3 published 4 yeasr ago by @mesmotronic, do you have (co)-ownership there with the ability to publish?
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
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.
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.
Hi Bernardo, nice work!
I have one issue:
If you go to: http://sslweb.azurewebsites.net/
Result on phones (tested on android and windows phone)
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
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]
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!
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.
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.
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
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?
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.
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
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.