Skip to content

Commit

Permalink
feat: add mouseOnly option
Browse files Browse the repository at this point in the history
  • Loading branch information
tsvetomir committed Mar 15, 2018
1 parent bb15b7b commit c563d57
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 18 deletions.
29 changes: 25 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,9 @@ The Kendo UI Draggable supports:

- Mouse events
- Touch events
- Pointer events
- Handling of multiple touches. Rather, not getting confused by them.

## What's Next

Support for Pointer events support, necessary for the Windows Phone platform.

## Dragging on iOS/Android

Handling the drag sequence on mobile devices may require the disabling of the touch-based scrolling. The Draggable will not do that out of the box. The recommended way to handle this issue is by setting a [`touch-action`](https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action) CSS property. Depending on the type of drags that are handled, you may need `touch-action: none`, `touch-action: pan-y`, or `touch-action: pan-x`.
Expand All @@ -92,6 +89,30 @@ Handling the drag sequence on mobile devices may require the disabling of the to

The dragging of elements that contain text activates the browser text selection, which, in most cases, is not desirable. To avoid this behavior, use the [`user-select: none`](https://developer.mozilla.org/en-US/docs/Web/CSS/user-select) CSS property with its respective browser prefixes.

## Mouse-Only mode

To ignore all touch and pointer events, set `mouseOnly` to `true`. This is useful when you want to keep the default touch-drag behavior, e.g. horizontal scroll.

```javascript
import Draggable from '@telerik/kendo-draggable';

const draggable = new Draggable({
mouseOnly: true,
press: function(e) {
console.log("pressed", e.pageX, e.pageY);
},
drag: function(e) {
console.log("drag", e.pageX, e.pageY);
},
release: function(e) {
console.log("release", e.pageX, e.pageY);
}
});

draggable.bindTo(document.getElementById("my-element"));
```


## Browser Support

- Google Chrome
Expand Down
25 changes: 25 additions & 0 deletions e2e/draggable-compat.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,29 @@ describe('Draggable with Mouse and Touch events fallback', () => {
clock.uninstall();
});
});

describe("with mouseOnly set to true", () => {
beforeEach(() => {
handler = jasmine.createSpy("onPress");

draggable = new Draggable({
press: handler,
mouseOnly: true
});

draggable.bindTo(el);
});

it("emits press on mousedown", () => {
mousedown(el, 100, 200);

expect(handler).toHaveBeenCalled();
});

it("does not emit press on touchstart", () => {
touchstart(el, 100, 200);

expect(handler).not.toHaveBeenCalled();
});
});
});
19 changes: 19 additions & 0 deletions e2e/draggable.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,5 +147,24 @@ describe('Draggable with Pointer events', () => {
expect(el.style.touchAction).toEqual('pan-y');
});
});

describe("with mouseOnly set to true", () => {
beforeEach(() => {
handler = jasmine.createSpy("onPress");

draggable = new Draggable({
press: handler,
mouseOnly: true
});

draggable.bindTo(el);
});

it("does not emit press on pointerdown", () => {
pointerdown(el, 100, 200);

expect(handler).not.toHaveBeenCalled();
});
});
});

3 changes: 2 additions & 1 deletion src/main.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
interface DraggableOptions {
press?: Function,
drag?: Function,
release?: Function
release?: Function,
mouseOnly?: boolean
}

export default class Draggable {
Expand Down
46 changes: 33 additions & 13 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ export class Draggable {
return window.PointerEvent;
}

constructor({ press = noop, drag = noop, release = noop }) {
constructor({ press = noop, drag = noop, release = noop, mouseOnly = false }) {
this._pressHandler = proxy(normalizeEvent, press);
this._dragHandler = proxy(normalizeEvent, drag);
this._releaseHandler = proxy(normalizeEvent, release);
this._ignoreMouse = false;
this._mouseOnly = mouseOnly;
this._touchAction;

this._touchstart = (e) => {
Expand Down Expand Up @@ -133,31 +134,50 @@ export class Draggable {
}

this._element = element;
this._bindToCurrent();
}

_bindToCurrent() {
const element = this._element;

if (Draggable.supportPointerEvent()) {
if (this._usePointers()) {
bind(element, "pointerdown", this._pointerdown);
bind(element, "pointerup", this._pointerup);
} else {
bind(element, "mousedown", this._mousedown);
return;
}

bind(element, "mousedown", this._mousedown);

if (!this._mouseOnly) {
bind(element, "touchstart", this._touchstart);
bind(element, "touchmove", this._touchmove);
bind(element, "touchend", this._touchend);
}
}

_unbindFromCurrent() {
if (Draggable.supportPointerEvent()) {
unbind(this._element, "pointerdown", this._pointerdown);
unbind(this._element, "pointermove", this._pointermove);
unbind(this._element, "pointerup", this._pointerup);
} else {
unbind(this._element, "mousedown", this._mousedown);
unbind(this._element, "touchstart", this._touchstart);
unbind(this._element, "touchmove", this._touchmove);
unbind(this._element, "touchend", this._touchend);
const element = this._element;

if (this._usePointers()) {
unbind(element, "pointerdown", this._pointerdown);
unbind(element, "pointermove", this._pointermove);
unbind(element, "pointerup", this._pointerup);
return;
}

unbind(element, "mousedown", this._mousedown);

if (!this._mouseOnly) {
unbind(element, "touchstart", this._touchstart);
unbind(element, "touchmove", this._touchmove);
unbind(element, "touchend", this._touchend);
}
}

_usePointers() {
return !this._mouseOnly && Draggable.supportPointerEvent();
}

destroy() {
this._unbindFromCurrent();
this._element = null;
Expand Down

0 comments on commit c563d57

Please sign in to comment.