سؤال

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.

هل كانت مفيدة؟

المحلول

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

نصائح أخرى

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]
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top