2015-10-23 19 views
9

http://jsfiddle.net/ujty083a/4/jQueryUI scorrimento automatico sul trascinamento

$(document).ready(function(){ 
     $(".left ul li").draggable({ 
      refreshPosition: true, 
      revert: true 
     }); 

     $(".right li").droppable({ 
      drop: function(e, ui){ 
       alert(ui.draggable.text()+" "+$(this).text()); 
      } 
     }); 

    }); 

ho tre liste uno è possibile trascinare e l'altra due accettare goccia. Gli elenchi giusti possono avere o meno una barra di scorrimento, ma ci saranno sempre 2 o più.

Il primo problema che ho riscontrato è quando l'elenco superiore ha una barra di scorrimento e si tenta di rilasciare un elemento nel secondo elenco vengono attivati ​​due eventi. Uno per la lista nascosta e uno per la lista visibile.

Il secondo problema è quando uno degli elenchi ha una barra di scorrimento che non scorre automaticamente quando l'utente trascina un elemento in esso.

risposta

4

penso che sarà necessario modificare droppable e modificare sostanzialmente alcuni dei comportamenti in questo modo:

  • Avrai bisogno di aggiungere un'opzione per definire se il droppable dovrebbe essere scorrevole oppure no.
  • Quindi è necessario un qualche tipo di convalida su quale droppable sono visibili o meno.
  • E avrete bisogno di modificare il comportamento di scorrimento che sono già presenti in alcuni widget di jquery ui.

Questo non è perfetto, ma dovrebbe darvi alcune idee:

$.widget('ui.droppable', $.ui.droppable, { 

     _over: function (e, ui) { 
      var draggable = $.ui.ddmanager.current; 
      if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return; // Bail if draggable and droppable are same element 

      // this to make sure the droppable is visible 
      this.scrollVisible = this._isScrollIntoView(); 

      if (this.accept.call(this.element[0], (draggable.currentItem || draggable.element)) && (!this.options.scrollable || this.scrollVisible)) { 

       if (this.options.hoverClass) { 
        this.element.addClass(this.options.hoverClass); 
       } 
       // to activate scrollable you need to change scrollParent of the draggable 
       // and adjust some calculations 
       if (this.options.scrollable) { 
        draggable.overflowOffset = $(this.element).scrollParent().offset(); 
        draggable.scrollParent = $(this.element).scrollParent(); 
        draggable.offsetParent = $(this.element).scrollParent(); 
        draggable.offset.parent.top = $(this.element).scrollParent().scrollTop(); 
       } 
       this._trigger('over', event, this.ui(draggable)); 
      } 


     }, 
     _out: function (event) { 

      this._super(); 
      var draggable = $.ui.ddmanager.current; 

      // remove scrollable 
      if (this.options.scrollable) { 
       draggable.scrollParent = $(document); 
       draggable.offsetParent = $(document); 
       draggable.overflowOffset = $(document).offset(); 
       draggable.offset.parent.top = $(document).scrollTop(); 
      } 
     }, 
     _drop: function (event, custom) { 

      var draggable = custom || $.ui.ddmanager.current; 
      if (!draggable || (draggable.currentItem || draggable.element)[0] == this.element[0]) return false; // Bail if draggable and droppable are same element 

      var childrenIntersection = false; 
      this.element.find(":data(droppable)").not(".ui-draggable-dragging").each(function() { 
       var inst = $.data(this, 'droppable'); 
       if (
       inst.options.greedy && !inst.options.disabled && inst.options.scope == draggable.options.scope && inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) && $.ui.intersect(draggable, $.extend(inst, { 
        offset: inst.element.offset() 
       }), inst.options.tolerance)) { 
        childrenIntersection = true; 
        return false; 
       } 
      }); 
      if (childrenIntersection) return false; 

      // same as for over, you need to validate visibility of the element 
      this.scrollVisible = this._isScrollIntoView(); 

      if (this.accept.call(this.element[0], (draggable.currentItem || draggable.element)) && (!this.options.scrollable || this.scrollVisible)) { 
       if (this.options.activeClass) this.element.removeClass(this.options.activeClass); 
       if (this.options.hoverClass) this.element.removeClass(this.options.hoverClass); 
       this._trigger('drop', event, this.ui(draggable)); 
       return this.element; 
      } 

      return false; 

     }, 
     // a function to check visibility. Taken here: 
     //http://stackoverflow.com/questions/487073/check-if-element-is-visible-after-scrolling 
     _isScrollIntoView() { 

      var $elem = $(this.element); 
      var $parent = $(this.element).scrollParent(); 

      var docViewTop = $parent.parent().scrollTop(); 
      var docViewBottom = docViewTop + $parent.parent().height(); 

      var elemTop = $elem.offset().top; 
      var elemBottom = elemTop + $elem.height(); 

      return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop)); 
     } 
    }); 



    $(document).ready(function() { 
     $(".left ul li").draggable({ 
      refreshPosition: true, 
      revert: true, 

     }); 

     $(".right .top li").droppable({ 
      scrollable: true, 

      drop: function (e, ui) { 
       alert(ui.draggable.text() + " " + $(this).text()); 
      } 
     }); 
     $(".right .bottom li").droppable({ 
      scrollable: false, 

      drop: function (e, ui) { 
       alert(ui.draggable.text() + " " + $(this).text()); 
      } 
     }); 

    }); 

http://jsfiddle.net/ejv32oen/4/

+0

Certamente otterrà me vicino. Grazie per l'aiuto. –

Problemi correlati