From 429dc043abc681a7d9d309462a81c7ab71519fc4 Mon Sep 17 00:00:00 2001 From: ChiefORZ Date: Mon, 22 Jun 2015 17:04:13 +0200 Subject: [PATCH] fix click event for mobile devices and old browser added forcePolyfill option. forcePolyfill is made to make cross-browser testing more easy. forcePolyfill provides a reliable, consistent cross-browser Solution for Sortable. forcePolyfill gives us the possibility to change the way "dragged items" lok like. --- README.md | 19 +++++++++++++++++ Sortable.js | 59 +++++++++++++++++++++++++++++++++------------------- package.json | 2 +- 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index cc767bb..411cd53 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,13 @@ var sortable = new Sortable(el, { ghostClass: "sortable-ghost", // Class name for the drop placeholder dataIdAttr: 'data-id', + /* + ignore the HTML5 DnD behaviour and force the fallback to kick in + - provide a more reliable cross-browser solution + - grants the ability to display a different "dragged" element + */ + forcePolyfill: false, + scroll: true, // or HTMLElement scrollSensitivity: 30, // px, how near the mouse must be to an edge to start scrolling. scrollSpeed: 10, // px @@ -253,6 +260,18 @@ Sortable.create(list, { --- +#### `forcePolyfill` option +If set to `true`, the polyfill - or Fallback for non HTML5 Browser - will be used, even if we are using an HTML5 Browser. +This gives us the possiblity to test the behaviour for older Browsers even in newer Browser, or make the Drag 'n Drop feel more consistent between Desktop , Mobile and old Browsers. + +On top of that, the polyfill always generates a copy of that DOM Element in the Document's Body. This behaviour can be exploited to give us more control over the look of this 'dragged' Element. + +Demo: http://jsbin.com/zejimolava/edit?html,css,js,output + + +--- + + #### `scroll` option If set to `true`, the page (or sortable-area) scrolls when coming to an edge. diff --git a/Sortable.js b/Sortable.js index ba23977..76a5a70 100644 --- a/Sortable.js +++ b/Sortable.js @@ -176,7 +176,8 @@ dropBubble: false, dragoverBubble: false, dataIdAttr: 'data-id', - delay: 0 + delay: 0, + forcePolyfill: false }; @@ -323,8 +324,12 @@ _on(ownerDocument, 'touchcancel', _this._onDrop); if (options.delay) { - // If the user moves the pointer before the delay has been reached: + // If the user moves the pointer or let go the click or touch + // before the delay has been reached: // disable the delayed drag + _on(ownerDocument, 'mouseup', _this._disableDelayedDrag); + _on(ownerDocument, 'touchend', _this._disableDelayedDrag); + _on(ownerDocument, 'touchcancel', _this._disableDelayedDrag); _on(ownerDocument, 'mousemove', _this._disableDelayedDrag); _on(ownerDocument, 'touchmove', _this._disableDelayedDrag); @@ -339,7 +344,9 @@ var ownerDocument = this.el.ownerDocument; clearTimeout(this._dragStartTimer); - + _off(ownerDocument, 'mouseup', this._disableDelayedDrag); + _off(ownerDocument, 'touchend', this._disableDelayedDrag); + _off(ownerDocument, 'touchcancel', this._disableDelayedDrag); _off(ownerDocument, 'mousemove', this._disableDelayedDrag); _off(ownerDocument, 'touchmove', this._disableDelayedDrag); }, @@ -355,7 +362,7 @@ this._onDragStart(tapEvt, 'touch'); } - else if (!supportDraggable) { + else if (!supportDraggable || this.options.forcePolyfill) { this._onDragStart(tapEvt, true); } else { @@ -422,6 +429,12 @@ _onTouchMove: function (/**TouchEvent*/evt) { if (tapEvt) { + // only set the status to dragging, when we are actually dragging + if(!Sortable.active) { + this._dragStarted(); + } + // as well as creating the ghost element on the document body + this._appendGhost(); var touch = evt.touches ? evt.touches[0] : evt, dx = touch.clientX - tapEvt.clientX, dy = touch.clientY - tapEvt.clientY, @@ -438,20 +451,8 @@ } }, - - _onDragStart: function (/**Event*/evt, /**boolean*/useFallback) { - var dataTransfer = evt.dataTransfer, - options = this.options; - - this._offUpEvents(); - - if (activeGroup.pull == 'clone') { - cloneEl = dragEl.cloneNode(true); - _css(cloneEl, 'display', 'none'); - rootEl.insertBefore(cloneEl, dragEl); - } - - if (useFallback) { + _appendGhost: function() { + if(!ghostEl) { var rect = dragEl.getBoundingClientRect(), css = _css(dragEl), ghostRect; @@ -466,12 +467,28 @@ _css(ghostEl, 'position', 'fixed'); _css(ghostEl, 'zIndex', '100000'); - rootEl.appendChild(ghostEl); + document.body.appendChild(ghostEl); // Fixing dimensions. ghostRect = ghostEl.getBoundingClientRect(); _css(ghostEl, 'width', rect.width * 2 - ghostRect.width); _css(ghostEl, 'height', rect.height * 2 - ghostRect.height); + } + }, + + _onDragStart: function (/**Event*/evt, /**boolean*/useFallback) { + var dataTransfer = evt.dataTransfer, + options = this.options; + + this._offUpEvents(); + + if (activeGroup.pull == 'clone') { + cloneEl = dragEl.cloneNode(true); + _css(cloneEl, 'display', 'none'); + rootEl.insertBefore(cloneEl, dragEl); + } + + if (useFallback) { if (useFallback === 'touch') { // Bind touch events @@ -493,9 +510,9 @@ } _on(document, 'drop', this); + setTimeout(this._dragStarted, 0); } - - setTimeout(this._dragStarted, 0); + }, _onDragOver: function (/**Event*/evt) { diff --git a/package.json b/package.json index 344c30b..f92bbad 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sortablejs", "exportName": "Sortable", - "version": "1.2.1", + "version": "1.2.2", "devDependencies": { "grunt": "*", "grunt-version": "*",