Pergunta

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.

Foi útil?

Solução

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));
  }

Outras dicas

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]
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top