jQuery draggable pokazuje helpera w niewłaściwym miejscu po przewinięciu strony

Używam jQuery draggable i droppable do tworzenia systemu planowania pracy. Użytkownicy przeciągają zadania do innego dnia lub użytkownika, a następnie dane są aktualizowane za pomocą połączenia ajax.

Wszystko działa dobrze, z wyjątkiem przewijania w dół strony głównej (zadania pojawiają się na dużym Planerze tygodniowym, który przekracza dno okna przeglądarki). Jeśli spróbuję przeciągnąć przeciągalny element tutaj, element pojawi się nad moim kursorem myszy tyle samo pikseli, ile przewijałem w dół.. Stan najazdu nadal działa dobrze, a funkcjonalność jest włączona, ale nie wygląda dobrze.

Używam jQuery 1.6.0 i jQuery UI 1.8.12.

Jestem pewien, że jest funkcja offset, którą muszę dodać, ale nie wiem, gdzie ją zastosować, lub czy jest lepszy sposób. Oto mój .draggable() kod inicjalizacji:

$('.job').draggable({
  zIndex: 20,
  revert: 'invalid',
  helper: 'original',
  distance: 30,
  refreshPositions: true,
});
Wiesz, co mogę zrobić, żeby to naprawić?
Author: Alex, 2011-04-26

19 answers

To może być powiązany raport o błędzie, istnieje już od dłuższego czasu: http://bugs.jqueryui.com/ticket/3740

Wydaje się, że dzieje się to na każdej przeglądarce, którą testowałem (Chrome, FF4, IE9). Istnieje kilka sposobów obejścia tego problemu:

1. użyj position:absolute; w css. Absolutnie pozycjonowane elementy nie wydają się mieć wpływu.

2. upewnij się, że element nadrzędny (event, jeśli jest ciałem) ma overflow:auto; ustawione. Mój test pokazał, że to rozwiązanie rozwiązuje pozycji, ale wyłącza funkcję autoscroll. Nadal można przewijać za pomocą kółka myszy lub klawiszy strzałek.

3. Zastosuj poprawkę sugerowaną w powyższym zgłoszeniu błędu ręcznie i przetestuj dokładnie, czy spowoduje to inne problemy.

4. poczekaj na oficjalną poprawkę. Jest zaplanowany do jQuery UI 1.9, chociaż został przełożony kilka razy w przeszłości.

5. Jeśli masz pewność, że dzieje się to w każdej przeglądarce, możesz umieścić te hacki do zdarzeń dotkniętych przeciągami, aby skorygować obliczenia. Jest to jednak wiele różnych przeglądarek do przetestowania, więc powinno być używane tylko w ostateczności: {]}

$('.drag').draggable({
   scroll:true,
   start: function(){
      $(this).data("startingScrollTop",$(this).parent().scrollTop());
   },
   drag: function(event,ui){
      var st = parseInt($(this).data("startingScrollTop"));
      ui.position.top -= $(this).parent().scrollTop() - st;
   }
});
 101
Author: DarthJDG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-26 20:09:59

To rozwiązanie działa bez regulacji pozycjonowania czegokolwiek, wystarczy sklonować element i uczynić go absolutnie pozycjonowanym.

$(".sidebar_container").sortable({
  ..
  helper: function(event, ui){
    var $clone =  $(ui).clone();
    $clone .css('position','absolute');
    return $clone.get(0);
  },
  ...
});

Helper może być funkcją, która musi zwrócić element DOM do przeciągnięcia.

 42
Author: mordy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-06 10:54:04

To mi pomogło:

start: function (event, ui) {
   $(this).data("startingScrollTop",window.pageYOffset);
},
drag: function(event,ui){
   var st = parseInt($(this).data("startingScrollTop"));
   ui.position.top -= st;
},
 11
Author: Ashraf Fayad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-26 19:43:32

Przepraszam za napisanie kolejnej odpowiedzi. Ponieważ żadne z rozwiązań w powyższej odpowiedzi nie może być przeze mnie użyte, zrobiłem dużo googlowania i zrobiłem wiele frustrujących drobnych zmian, zanim znalazłem inne rozsądne rozwiązanie.

Ten problem wydaje się występować, gdy dowolne z elementów nadrzędnych mają position ustawione na 'relative'. Musiałem przetasować znaczniki I zmienić mój CSS, ale usuwając tę właściwość ze wszystkich rodziców, byłem w stanie uzyskać .sortable() działa poprawnie we wszystkich przeglądarkach.

 7
Author: Joshua Bambrick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-13 17:01:50

Wygląda na to, że ten błąd pojawia się bardzo często i za każdym razem pojawia się inne rozwiązanie. Żadne z powyższych, ani nic innego, co znalazłem w Internecie nie działało. Używam jQuery 1.9.1 i jQuery UI 1.10.3. Tak to naprawiłem:

$(".dragme").draggable({
  appendTo: "body",
  helper: "clone",
  scroll: false,
  cursorAt: {left: 5, top: 5},
  start: function(event, ui) {
    if(! $.browser.chrome) ui.position.top -= $(window).scrollTop();
  },
  drag: function(event, ui) {
    if(! $.browser.chrome) ui.position.top -= $(window).scrollTop();
  }
});

Działa w FF, IE, Chrome, nie testowałem go jeszcze w innych przeglądarkach.

 7
Author: kazmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-05 04:18:34

Ten błąd został przeniesiony do http://bugs.jqueryui.com/ticket/6817 i, od około 5 dni temu (16 grudnia 2013 lub tam) wydaje się, że w końcu zostały naprawione. Teraz sugerujemy użycie najnowszej wersji deweloperskiej http://code.jquery.com/ui/jquery-ui-git.js {[2] } lub czekać na wersję 1.10.4, która powinna zawierać tę poprawkę .

Edit: Wygląda na to, że ta poprawka może być teraz częścią http://bugs.jqueryui.com/ticket/9315 który nie jest zaplanowany do upuść do wersji 1.11. Używanie powyższej, połączonej wersji kontrolnej źródła jQuery wydaje się naprawiać problem dla mnie i @ Scott Alexander(komentarz poniżej).

 5
Author: Patrick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-28 15:53:47

Usuwam przepełnienie:

html {overflow-y: scroll; background: #fff;}

I działa idealnie!

 4
Author: Miguel Puig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-27 08:27:16

Wydaje się niezwykłe, że ten błąd powinien zostać naprawiony tak długo. Dla mnie jest to problem na Safari i Chrome (tj. przeglądarki webkit), ale nie na IE7/8/9 ani na Firefoksie, który wszystko działa dobrze.

Znalazłem to ustawienie absolutne lub stałe, z lub bez !ważne, nie pomogło więc w końcu dodałem linię do mojej funkcji drag handler:

ui.position.top += $( 'body' ).scrollTop();

Spodziewałem się, że będę musiał uczynić tę linię WebKit specyficznym, ale co ciekawe, wszędzie działało dobrze. (Spodziewaj się komentarza ode mnie wkrótce mówiąc "er Nie, właściwie to zepsuło wszystkie inne przeglądarki".)

 3
Author: Allen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-15 11:21:45

To co zrobiłem to:

$("#btnPageBreak").draggable(
        {
          appendTo: 'body',
          helper: function(event) {
            return '<div id="pageBreakHelper"><img  id="page-break-img"  src="page_break_cursor_red.png" /></div>';
          },
          start: function(event, ui) {
          },
          stop: function(event, ui) {
          },
          drag: function(event,ui){
            ui.helper.offset(ui.position);
         }
        });
 3
Author: Pankaj Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-13 13:53:08

Nie jestem do końca pewien, czy to zadziała w każdym przypadku, ale to obejście, które zrobiłem, działało dla mnie na wszystkich różnych sytuacjach, które musiałem przetestować (i gdzie poprzednie proponowane rozwiązania podane tutaj i gdzie indziej zawiodły)

(function($){
$.ui.draggable.prototype._getRelativeOffset = function()
{
    if(this.cssPosition == "relative") {
        var p = this.element.position();
        return {
            top: p.top - (parseInt(this.helper.css("top"),10) || 0)/* + this.scrollParent.scrollTop()*/,
            left: p.left - (parseInt(this.helper.css("left"),10) || 0)/* + this.scrollParent.scrollLeft()*/
        };
    } else {
        return { top: 0, left: 0 };
    }
};
}(jQuery));

( zgłosiłem to do jQuery.tracker interfejsu użytkownika, aby zobaczyć, co o tym myślą.. byłoby fajnie, gdyby ten 4-letni błąd mógł zostać w końcu poprawiony:/)

 1
Author: vor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-26 10:04:21

Używam JQuery draggable na Firefoksie 21.0 i mam ten sam problem. Kursor pozostaje o cal nad obrazem pomocniczym. Myślę, że jest to problem w samym Jquery, który nadal nie został rozwiązany. Znalazłem obejście tego problemu, którym jest użycie właściwości "cursorAt"przeciąganego. Użyłem go w następujący sposób, ale można to zmienić zgodnie z jego wymaganiami.

$('.dragme').draggable({
helper: 'clone',    
cursor: 'move',    
cursorAt: {left: 50, top: 80}
});

Uwaga: będzie to miało zastosowanie dla wszystkich przeglądarek, więc po użyciu tego kodu sprawdź swoją stronę we wszystkich przeglądarkach, aby uzyskać poprawną lewą i górną pozycję.

 1
Author: impiyush,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-18 16:05:36

To mi się udało, po dostosowaniu wszystkiego, co przeczytałem na temat problemu.

$(this).draggable({
  ...
  start: function (event, ui) {
    $(this).data("scrollposTop", $('#elementThatScrolls').scrollTop();
    $(this).data("scrollposLeft", $('#elementThatScrolls').scrollLeft();
  },
  drag: function (event, ui) {
    ui.position.top += $('#elementThatScrolls').scrollTop();
    ui.position.left += $('#elementThatScrolls').scrollLeft();
  },
  ...
}); 

*elementThatScrolls jest rodzicem lub przodkiem z overflow:auto;

Ustala pozycję przewijanego elementu i dodaje pozycję pomocnika za każdym razem, gdy jest przesuwany / przeciągany.

Mam nadzieję, że to komuś pomoże, bo zmarnowałem na to sporo czasu.
 1
Author: Rnubi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-01 13:26:58

To wygląda na obejście bez potrzeby używania position: absolute w rodzicu:)

$("body").draggable({
     drag: function(event, ui) { 
         return false; 
     } 
});
 1
Author: TomCe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-01 21:24:16

Udało mi się naprawić ten sam problem z dodaniem display: inline-block do przeciąganych elementów

Dodawanie position: relative nie działa dla mnie (jQuery nadpisuje go position: absolute przy przeciąganiu start)

Używane wersje jQuery:

  • jQuery-1.7.2
  • jQuery UI-1.11.4
 1
Author: Plamen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-30 10:21:43

Zrezygnowałem z używania jQueryUI draggable i przeniosłem się do lepszego pluginu o nazwie jquery.parzyste.drag , znacznie mniejszy rozmiar kodu, bez wszystkich bzdur jakie ma jQueryUI.

Zrobiłem stronę demo używając tej wtyczki wewnątrz kontenera, który ma pozycję: fixed

Demo

Mam nadzieję, że to komuś pomoże, bo ten problem jest duży.

 0
Author: vsync,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-09 05:03:34

Miałem podobny problem, tylko z konkretnym IE 10 działającym na Windows 8. Wszystkie inne przeglądarki działały dobrze. Usunięcie kursora: {top: 0 } rozwiązało problem.

 0
Author: nmm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-16 19:08:12

Próbowałem różnych odpowiedzi tutaj, w tym aktualizacji jQuery i okazało się, że to działa dla mnie. Testowałem to na najnowszych chrome i IE. Myślę, że będzie to problem z różnymi rozwiązaniami w zależności od układu interfejsu użytkownika.

$('{selector}').draggable({
    start: function(event, ui) {
        ui.position.top -= $(document).scrollTop();
    },
    drag: function(event, ui) {
        ui.position.top -= $(document).scrollTop();
    }
});
 0
Author: Lee Willis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-24 12:20:20

Dlaczego nie zająć pozycji kursora? używam wtyczki sortowalnej i naprawiam ją tym kodem:

sort: function(e, ui) {
    $(".ui-sortable-handle.ui-sortable-helper").css({'top':e.pageY});
}
 0
Author: Aztrozero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-03 01:35:49

Miałem ten sam problem i okazało się, że wszystko to było z powodu Bootstrap navbar "navbar-fixed-top" klasy z pozycji do stałej, które poruszają się w dół mój <body> 60px niższe niż <html> top. Więc kiedy przesuwałem przeciągalne formularze w mojej witrynie, kursor pojawił się 60px na górze formularza.

Widać, że w narzędziu debugowania Chrome, w interfejsie Elements, kliknij znacznik <body>, a zobaczysz lukę między topem a ciałem.

Ponieważ używam tego navbara we wszystkich moich aplikacjach i nie chciałem modyfikować mojego inicjującego wywołania, aby przeciągnąć (zgodnie z procedurą DarthJDG) dla każdego formularza. Postanowiłem rozszerzyć przeciągalny widget w ten sposób i po prostu dodać yOffset w mojej przeciągalnej inicjalizacji.

(function($) {
  $.widget("my-ui.draggable", $.ui.draggable, {
    _mouseDrag: function(event, noPropagation) {

      //Compute the helpers position
      this.position = this._generatePosition(event);
      this.positionAbs = this._convertPositionTo("absolute");

      //Call plugins and callbacks and use the resulting position if something is returned
      if (!noPropagation) {
        var ui = this._uiHash();
        if(this._trigger('drag', event, ui) === false) {
          this._mouseUp({});
          return false;
        }
        this.position = ui.position;
      }
      // Modification here we add yoffset in options and calculation
      var yOffset = ("yOffset" in this.options) ? this.options.yOffset : 0;

      if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';
      if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top-yOffset+'px';
      if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);

      return false;
    }
  });
})(jQuery);

Teraz, gdy inicjalizuję przeciągalny element / formularz w witrynie za pomocą Bootstrap navbar:

// Make the edit forms draggable
$("#org_account_pop").draggable({handle:" .drag_handle", yOffset: 60});

Oczywiście będziesz musiał eksperymentować, aby określić odpowiedni zestaw yOffset zgodnie z własną witryną.

W każdym razie dzięki DarthJDG, który wskazał mi właściwy kierunek. Zdrowie!

 0
Author: fled,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-29 10:36:32