Question

J'ai un problème avec une interface utilisateur jQuery 1.7.2 liste triable dans Firefox 3.6, IE7-8 excellent travail. Quand je suis un peu défile vers le bas, l'élément d'aide semble avoir un décalage de la même hauteur que je suis défiler vers le bas du pointeur de la souris qui ne permet pas de voir quel point vous avez initialement commencé à glisser. Comment puis-je résoudre ce problème ou de travail autour de la question? S'il n'y a pas de solution ce qui est un très bon plugin drag-mesure alternative?

Voici mes paramètres d'initialisation du sortable.

$("#sortable").sortable( {placeholder: 'ui-state-highlight'  } );
$("#sortable").disableSelection();
Était-ce utile?

La solution

Je voyais cette question et a pu le résoudre en supprimant la position de la règle css: relative d'un des divs contenant sur ma page. Voir aussi: http: //forum.jquery.com/topic/sortable-offset-when-element-is-dragged-and-page-scrolled-down-ff

Autres conseils

Si vous voulez éviter renifler navigateur, la CSS seule solution consiste à définir la ul ou un style de récipient pour overflow: auto. Si vous regardez la source à travers Firebug, c'est la façon dont il le fait jQuery dans leur exemple .

Utilisation overflow: auto; n'a pas été une option pour moi. J'ai pu contourner ce problème avec ce gestionnaire d'événements sort:

$(...).sortable({
    ...
    sort: function(event, ui) {
        var $target = $(event.target);
        if (!/html|body/i.test($target.offsetParent()[0].tagName)) {
            var top = event.pageY - $target.offsetParent().offset().top - (ui.helper.outerHeight(true) / 2);
            ui.helper.css({'top' : top + 'px'});
        }
    },
    ...
});

Il est pas parfait, mais il ne nécessite pas de renifler du navigateur. Testé dans IE8, Chrome et Firefox.

Modifier :. Ce utilise jQuery et jQuery UI 1.10.0 1.10.3

J'ai aussi eu ce problème et fixé avec le code suivant:

var wscrolltop = 0;
$sortable_elements.sortable({ 
    start: function(event, ui) {
        wscrolltop = $(window).scrollTop();
    },
    sort: function(event, ui) {                   
        ui.helper.css({'top' : ui.position.top + wscrolltop + 'px'});
    }
});

J'ai découvert, qu'il ya encore un problème si vous faites défiler avec votre triables-élément. Peut-être que quelqu'un a une solution pour cela?

Mise à jour: Le correctif est:

$sortable_elements.sortable({ 
    connectWith: '#personal-favs ul.fitems',
    sort: function(event, ui) {  
        ui.helper.css({'top' : ui.position.top + $(window).scrollTop() + 'px'});
    }
});

Mais encore -. Si vous quittez la liste, le genre événement semble arrêter

Vous devez également tenir compte du fait que c'est spécifique à Firefox, voici l'extrait que je utilise - je me suis dirigé la bonne façon de la solution de Harris. J'ai rencontré ce problème w / o en utilisant l'aide lorsque le triables était dans un récipient relativement positionné.

  var options = { 
   handle: '.mover', 
   update:updateSorting 
 };
  var userAgent = navigator.userAgent.toLowerCase();
  if(userAgent.match(/firefox/)) {
    options["start"] = function (event, ui) { ui.item.css('margin-top', $(window).scrollTop() ); };
    options["beforeStop"] = function (event, ui) { ui.item.css('margin-top', 0 ); };
  }
  $("#" + list_id+"").sortable(options);
  $("#" + list_id+"").disableSelection();

Vous pouvez également effectuer cette vérification sur le serveur et ensuite 2 différents appels en fonction du navigateur.

J'ai réussi à trouver une solution pour cela:

$( "items" ).sortable({
start: function (event, ui) {
 if( ui.helper !== undefined )
  ui.helper.css('position','absolute').css('margin-top', $(window).scrollTop() );
},
beforeStop: function (event, ui) {
 if( ui.offset !== undefined )
  ui.helper.css('margin-top', 0);
},
placeholder: 'placeholder-class'
});

En gros, vous devez écouter l'événement « start » de sortable pour ajouter la valeur actuelle scrollTop () du navigateur à la position de l'aide, et vous devez écouter l'événement « beforeStop » du sortable, pour supprimer ce décalage avant la article est officiellement remis dans la liste à sa nouvelle position.

L'espoir qui est utile à quelqu'un!

Je force mon site sur les barres de défilement si ce problème se produit en raison de décalage scrollable d'avoir html { overflow-y: scroll } dans mon CSS.

Comme je tourne scrollable sur et en dehors, je suit pour contourner. Je ne l'ai testé dans IE8, FF12 et Chrome ...

  turnSortingOnOff:function(e) {
    e.preventDefault();

    if (stopOrdering()) {
      // get rid of the hacky css on the html element
      $('html').css({ 'overflow-y': '' });
      $('html').css({ 'margin-right': '' });

      elmt.sortable('disable');
    }
    else if (startOrdering()) {
      // if the body is smaller than the window
      // then there aren't any scrollbars
      // in which case, add a right hand margin of 16px
      // to the html to prevent the site wobbling
      if ($('body').outerHeight() <= $(window).height()) {
        $('html').css({ 'margin-right': 16 });
      }

      // then override the { overflow-y: scroll }
      // in the css by setting it to a nice, safe inherit
      $('html').css({ 'overflow-y': 'inherit' });

      elmt.sortable('enable');
    }
  }

Il est évident que ce n'est pas l'épreuve des balles - si la taille du document change lors du tri puis d'autres choses devront faire. Cependant, dans mon expérience, il semble moins étrange dans ces circonstances.

I "fixe" en utilisant cette version jQuery UI / jQuery nouvelles.

  • jQuery 1.8.0
  • jQuery UI 1.8.23

Réglage overflow: auto fait démarrer Firefox le glisser avec l'élément sous le pointeur, mais il empêche également autoscroll de fonctionner correctement. Vous pouvez voir ce droit dans l'exemple jQuery Sortable, si vous faites assez petit la fenêtre que le défilement est nécessaire.

J'avais overflow: scroll sur la balise html, mais même enlever cela et (je pense) tous les éléments contenant par rapport n'a pas résolu totalement le problème (ce qui signifie la traînée démarre correctement et fonctionne AutoScroll). J'ai aussi essayé un patch renifleurs mozilla à _findRelativeOffset (je crois que ce), mais il n'a pas aidé.

Qu'est-ce que l'aide pour mon cas d'utilisation était juste un clone avec traîne (helper: 'clone' dans le constructeur draggable). Pour faire ressembler le clone était pas là, j'ai ajouté démarrer et arrêter des méthodes qui se trouve juste à l'visibilty caché puis revenir.

J'aurais commenté ci-dessus, mais je n'ai pas encore les points.

eu le même problème. Dans mon cas, il était pas possible d'utiliser le « overflow: auto » -fix. Voilà donc ce que je l'ai fait.

var pos_fixed = 1;        // switch variable (the fix should only be fired ones)
$('.drag').draggable({
 start: function(event, ui){
  pos_fixed = 0;            // we're about to start, set to not fixed yet
 },
 drag: function(event, ui){
  if(pos_fixed == 0){       // check if the fix hasn't been fired for this instance yet
   var help_pos = $(ui.helper).offset().top, // get helpers offset
   targ_pos = $(event.target).offset().top,  // get targets(the dragged elements) offset
   marg = targ_pos-help_pos; // calculate the margin the helper has to have to put it on the same y-position as our target
   $(ui.helper).css('margin-top', marg); // put our helper on the same y-position as the target
   pos_fixed = 1;            // we've fixed it, we don't want it to fire again
  }
 }
});

Le correctif ne se soucie pas de ce navigateur que vous utilisez. Il sera toujours faire en sorte que l'aide a le même décalage vertical que la cible lorsque la traînée commence.

Pour les futurs lecteurs de ce problème. Je suis passé de 1,8 à jQueryUI 1.10.3 et le problème a été résolu sans corrections css.

http://jqueryui.com/

J'ai aussi mis à jour de jquery 1,8 à 1.10.2

http://jquery.com/

Pour les futurs lecteurs Je suis tombé sur un problème similaire où l'élément d'aide a un décalage lors du déplacement à l'intérieur du div d'une boîte de dialogue défiler bootstrap. Lorsque vous relâchez l'objet déplacé, l'animation envoie l'élément d'aide traîné vers sa nouvelle position sans considérer la partie de la page défile, ce qui donne une rétroaction source de confusion pour les utilisateurs.

Afin de garder les choses à travailler avec position: relative et overflow-y: auto dans le récipient de dialogue, ma solution était

1- Ajoutez le scrollTop () offset à la marge supérieure sur l'objet d'assistance dans le genre début de l'événement;

2- supprimer la marge supérieure dans le cas beforeStop

fixée l'animation d'être éteint après draging, mais l'objet utilitaire est poussé au-dessous du curseur pendant le déplacement dans la partie défile dans la page. La dernière solution est

3- Calculer et définir la propriété supérieure de l'objet utilitaire tout en faisant glisser (en utilisant l'événement de tri) par rapport à l'aiguille et le récipient de compensation.

$(...).sortable({
...
start: function (event, ui) {  
    ui.helper.css('margin-top', $("#mybootstrap-dialog").scrollTop()); 
},
beforeStop: function (event, ui){ 
    ui.helper.css('margin-top',0); 
},
sort: function(event, ui) {
    var top = event.clientY - $('#my-sortable-ul').offset().top  -  $("#mybootstrap-dialog").scrollTop();
    ui.helper.css({'top' : top + 'px'});
    }
},
...

});

Aide cette aide

Pour résumer vos efforts et de fournir une solution terminée. Ce qui suit a semblé fonctionner pour Chrome et Firefox 30 40 + +

var isFirefox = /firefox/.test(navigator.userAgent.toLowerCase());
$('#target').sortable({
    connectWith: '#target-holder .elements',
    handle: ".element-header",
    start: function(ev, ui) {
        if( isFirefox ) {
            ui.item.css('margin-top', $(window).scrollTop() );
        }
    },
    sort: function(ev, ui) {
        if( isFirefox) {
            ui.helper.css({'top' : ui.position.top - $(window).scrollTop() + 'px'});
        } else {
            ui.helper.css({'top' : ui.position.top + $(window).scrollTop() + 'px'});
        }
    },
    beforeStop: function (ev, ui) {
        if( isFirefox ) {
            ui.item.css('margin-top', 0 );
        }
    }
});

Ma solution: ".sortable" pour ajouter la "position: relative"

$(".sortable").sortable({
      sort: function(event, ui) {
           ui.position.top = ui.position.top + $(window).scrollTop();
      },
});

PS utilisé jQuery UI 1.12.0 et jQuery 2.2.4

sort: function(e, ui){
        var tempVariable = $(ui.item.get(0));
        tempVariable.css('top', (e.clientY)-(tempVariable.css("height").replace("px", "")));
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top