Question

How would you setup touch events to the draggable class, so that it works on iOS (iPad's, iPhone's, etc)? I have read How can I make a jQuery UI 'draggable()' div draggable for touchscreen?, which has lots of options for jQuery, but not sure how to apply that to Scriptaculous. Any help would be appreciated. Thanks.

Était-ce utile?

La solution

You can do it by editing dragdrop.js as mention here:

In Draggables:

  register: function(draggable) {
    if(this.drags.length == 0) {
      this.eventMouseUp   = this.endDrag.bindAsEventListener(this);
      this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
      this.eventKeypress  = this.keyPress.bindAsEventListener(this);


      Event.observe(document, "mouseup", this.eventMouseUp);
      Event.observe(document, "mousemove", this.eventMouseMove);
      Event.observe(document, "keypress", this.eventKeypress);


      Event.observe(document, "touchstart", this.eventKeypress);
      Event.observe(document, "touchmove", this.eventMouseMove);
      Event.observe(document, "touchend", this.eventMouseUp);
    }
    this.drags.push(draggable);
  },


  unregister: function(draggable) {
    this.drags = this.drags.reject(function(d) { return d==draggable });
    if(this.drags.length == 0) {
      Event.stopObserving(document, "touchstart", this.eventKeypress);
      Event.stopObserving(document, "touchmove", this.eventMouseMove);
      Event.stopObserving(document, "touchend", this.eventMouseUp);


      Event.stopObserving(document, "mouseup", this.eventMouseUp);
      Event.stopObserving(document, "mousemove", this.eventMouseMove);
      Event.stopObserving(document, "keypress", this.eventKeypress);
    }
  },

In Draggable:

initialize:
...
    this.eventMouseDown = this.initDrag.bindAsEventListener(this);
    Event.observe(this.handle, "mousedown", this.eventMouseDown);
      Event.observe(this.handle, "touchstart", this.eventMouseDown);


    Draggables.register(this);
  },


  destroy: function() {
    Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
    Event.stopObserving(this.handle, "touchstart", this.eventMouseDown);
    Draggables.unregister(this);
  },

...

initDrag: function(event) {
    if(!Object.isUndefined(Draggable._dragging[this.element]) &&
      Draggable._dragging[this.element]) return;
    if(Event.isLeftClick(event) || event.type == "touchstart") {

Along with editing prototype.js:

function pointerX(event) {
    var docElement = document.documentElement,
     body = document.body || { scrollLeft: 0 };


    if (event.changedTouches) return (event.changedTouches[0].clientX +
      (docElement.scrollLeft || body.scrollLeft) -
      (docElement.clientLeft || 0));


    return event.pageX || (event.clientX +
      (docElement.scrollLeft || body.scrollLeft) -
      (docElement.clientLeft || 0));
  }


  function pointerY(event) {
    var docElement = document.documentElement,
     body = document.body || { scrollTop: 0 };


    if (event.changedTouches) return (event.changedTouches[0].clientY +
      (docElement.scrollTop || body.scrollTop) -
      (docElement.clientTop || 0));


    return  event.pageY || (event.clientY +
       (docElement.scrollTop || body.scrollTop) -
       (docElement.clientTop || 0));
  }

Autres conseils

I think, you have to use parseInt function for X,Y coordinates, because I have some problem with Chrome browser on Android-it put something like 23.45435435345345345345345 to coordinates.

//Add parseInt ----------------[start]  
if (event.changedTouches) return (parseInt(event.changedTouches[0].clientY +
      (docElement.scrollTop || body.scrollTop) -
      (docElement.clientTop || 0),10));
//Add parseInt ----------------[end]
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top