Używam przeciągania i upuszczania jQuery dla systemu planowania pracy, który tworzę . Użytkownicy przeciągają zadania do innego dnia lub użytkownika, a następnie dane są aktualizowane przy użyciu wywołania Ajax.
Wszystko działa dobrze, z wyjątkiem sytuacji, gdy przewijam stronę główną w dół (oferty pracy pojawiają się w dużym kalendarzu tygodniowym, który przekracza dolną część okna przeglądarki). Jeśli spróbuję przeciągnąć tutaj element, który można przeciągać, element pojawia się nad moim kursorem myszy z taką samą liczbą pikseli, jaką przewinąłem w dół. Stan najechania nadal działa dobrze, a funkcjonalność działa, ale nie wygląda dobrze.
Używam jQuery 1.6.0 i jQuery UI 1.8.12.
Jestem pewien, że muszę dodać funkcję przesunięcia, ale nie wiem, gdzie ją zastosować lub czy jest lepszy sposób. Oto mój .draggable()
kod inicjalizacyjny:
$('.job').draggable({
zIndex: 20,
revert: 'invalid',
helper: 'original',
distance: 30,
refreshPositions: true,
});
Masz jakiś pomysł, co mogę zrobić, aby to naprawić?
Odpowiedzi:
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 w każdej testowanej przeglądarce (Chrome, FF4, IE9). Istnieje kilka sposobów obejścia tego problemu:
1. Użyj
position:absolute;
w swoim css. Wydaje się, że nie ma to wpływu na elementy pozycjonowane absolutnie.2. Upewnij się, że element nadrzędny (zdarzenie, jeśli jest treścią) został
overflow:auto;
ustawiony. Mój test wykazał, że to rozwiązanie naprawia pozycję, ale wyłącza funkcję automatycznego przewijania. Nadal możesz przewijać za pomocą kółka myszy lub klawiszy strzałek.3. Zastosuj poprawkę sugerowaną w powyższym zgłoszeniu błędu ręcznie i dokładnie przetestuj, czy powoduje inne problemy.
4. Poczekaj na oficjalną poprawkę. Zaplanowano na jQuery UI 1.9, chociaż w przeszłości było to kilka razy odkładane.
5. Jeśli masz pewność, że dzieje się to w każdej przeglądarce, możesz umieścić te hacki w zdarzeniach draggables, których dotyczy ten problem, aby poprawić obliczenia. Do przetestowania jest jednak wiele różnych przeglądarek, więc należy go używać 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; } });
źródło
helper: "clone"
. bugs.jqueryui.com/ticket/9315 Poziom bloker , wycięcie powyżej major. tj.vantoll mówi, że „6 możliwych do przeciągnięcia poprawek, które wylądowały w wersji 1.10.3, może być podejrzanych”. Najprostszy jak dotąd przykład: jsfiddle.net/7AxXETo rozwiązanie działa bez dostosowywania pozycji czegokolwiek, po prostu klonujesz element i ustawiasz go absolutnie.
$(".sidebar_container").sortable({ .. helper: function(event, ui){ var $clone = $(ui).clone(); $clone .css('position','absolute'); return $clone.get(0); }, ... });
Pomocnikiem może być funkcja, która musi zwrócić element DOM do przeciągnięcia.
źródło
To zadziałało dla mnie:
start: function (event, ui) { $(this).data("startingScrollTop",window.pageYOffset); }, drag: function(event,ui){ var st = parseInt($(this).data("startingScrollTop")); ui.position.top -= st; },
źródło
"1.11.0"
Przepraszam za napisanie innej odpowiedzi. Ponieważ żadne z rozwiązań w powyższej odpowiedzi nie mogło być przeze mnie użyte, dużo googlowałem i wprowadziłem wiele frustrujących drobnych zmian, zanim znalazłem inne rozsądne rozwiązanie.
Wydaje się, że ten problem występuje, gdy którykolwiek z elementów nadrzędnych został
position
ustawiony jako „względny”. Musiałem przetasować moje znaczniki i zmienić CSS, ale usuwając tę właściwość ze wszystkich rodziców, mogłem.sortable()
działać poprawnie we wszystkich przeglądarkach.źródło
position: relative;
rodzic powoduje to.position: relative;
którym trzeba było usunąć ... elementy nadrzędne między ciągnikiem a ciałem wydają się nie powodować tutaj problemów ..Wygląda na to, że ten błąd pojawia się bardzo często i za każdym razem jest 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. Oto jak 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, jeszcze nie testowałem tego w innych przeglądarkach.
źródło
Usuwam przepełnienie:
html {overflow-y: scroll; background: #fff;}
I działa idealnie!
źródło
Ten błąd został przeniesiony na http://bugs.jqueryui.com/ticket/6817 i wydaje się, że około 5 dni temu (16 grudnia 2013 r. Lub później) został ostatecznie naprawiony. Sugeruje się teraz, aby użyć najnowszej kompilacji deweloperskiej z http://code.jquery.com/ui/jquery-ui-git.js lub poczekać na
wersję 1.10.4, która powinna zawierać tę poprawkę.Edycja: Wygląda na to, że ta poprawka może być teraz częścią http://bugs.jqueryui.com/ticket/9315, która ma zostać usunięta do wersji 1.11. Wydaje się, że użycie powyższej wersji jQuery, połączonej z kontrolą źródła, rozwiązuje problem dla mnie i @Scott Alexander (komentarz poniżej).
źródło
Wydaje się niezwykłe, że ten błąd powinien zniknąć tak długo. Dla mnie jest to problem w Safari i Chrome (czyli przeglądarkach webkit), ale nie w IE7 / 8/9 ani w Firefoksie, które działają dobrze.
Zauważyłem, że ustawienie bezwzględne lub stałe, z lub bez! Ważne, nie pomogło, więc ostatecznie dodałem linię do mojej funkcji obsługi przeciągania:
ui.position.top += $( 'body' ).scrollTop();
Spodziewałem się, że będę musiał uczynić tę linię specyficzną dla zestawu internetowego, ale co ciekawe, wszędzie działała dobrze. (Wkrótce spodziewaj się ode mnie komentarza mówiącego „eee nie, w rzeczywistości zepsuło to wszystkie inne przeglądarki”).
źródło
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); } });
źródło
Nie jestem do końca pewien, czy to zadziała w każdym przypadku, ale to obejście, które właśnie wykonałem dla mnie we 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));
(Przesłałem to do modułu śledzącego jQuery.ui, aby zobaczyć, co o tym sądzą ... byłoby fajnie, gdyby ten 4-letni błąd mógł zostać w końcu poprawiony: /)
źródło
Używam przeciągania JQuery w przeglądarce Firefox 21.0 i mam ten sam problem. Kursor pozostaje cal nad obrazem pomocniczym. Myślę, że jest to problem w samym Jquery, który wciąż nie został rozwiązany. Znalazłem obejście tego problemu, które polega na użyciu właściwości „cursorAt” elementu draggable. 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 do wszystkich przeglądarek, więc po użyciu tego kodu sprawdź swoją stronę we wszystkich przeglądarkach, aby uzyskać prawidłowe lewe i górne pozycje.
źródło
To właśnie zadziałało u mnie, 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 przepełnieniem: auto;
Wylicza pozycję przewijanego elementu i dodaje do pozycji pomocnika za każdym razem, gdy jest on przesuwany / przeciągany.
Mam nadzieję, że to komuś pomoże, ponieważ zmarnowałem na to więcej czasu.
źródło
Wydaje się, że rozwiązuje to problem bez konieczności używania pozycji: bezwzględna w rodzicu :)
$("body").draggable({ drag: function(event, ui) { return false; } });
źródło
Udało mi się rozwiązać ten sam problem z dodawaniem
display: inline-block
do przeciągniętych elementówDodawanie
position: relative
NIE zadziałało dla mnie (jQuery nadpisuje to przyposition: absolute
drag start)Używane wersje jQuery:
źródło
position: relative
mogło zadziałać, jeśli przeniesiesz go do elementu kontenera wyższego poziomu. Wiem, że teraz to nie pomaga, ale tylko w celach informacyjnych i może dla przyszłego, niespokojnego programisty.Miałem ten sam problem i stwierdziłem, że wszystko to było spowodowane klasą bootstrap "navbar-fixed-top" z pozycją do ustalonej, która przesuwała się w dół o
<body>
60px niżej niż na<html>
górze. Kiedy więc przesuwałem w witrynie formularze, które można przeciągać, na górze formularza pojawił się kursor 60 pikseli.Możesz zobaczyć, że w narzędziu do debugowania Chrome, w interfejsie Elements, kliknij
<body>
tag, a zobaczysz lukę między górą a treścią.Ponieważ używam tego paska nawigacyjnego we wszystkich moich aplikacjach i nie chciałem modyfikować wywołania inicjującego do przeciągania (zgodnie z procedurą DarthJDG) dla każdego formularza. Zdecydowałem się w ten sposób rozszerzyć widżet draggable i po prostu dodać yOffset do mojej inicjalizacji draggable.
(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, kiedy inicjalizuję przeciągany element / formularz w witrynie za pomocą paska nawigacyjnego bootstrap:
// Make the edit forms draggable $("#org_account_pop").draggable({handle:" .drag_handle", yOffset: 60});
Oczywiście będziesz musiał poeksperymentować, aby określić właściwy yOffset zgodnie z własną witryną.
W każdym razie dziękuję DarthJDG, który wskazał mi właściwy kierunek. Twoje zdrowie!
źródło
Porzuciłem używanie draggable jQueryUi i przeniosłem się do lepszej wtyczki o nazwie jquery.even.drag , o znacznie mniejszym rozmiarze kodu, bez wszystkich bzdur, jakie ma jQueryUI.
Zrobiłem stronę demonstracyjną za pomocą tej wtyczki wewnątrz kontenera, który ma pozycję: naprawiono
Próbny
Mam nadzieję, że to komuś pomoże, ponieważ ten problem jest DUŻY.
źródło
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 kursoraAt: {top: 0} rozwiązało problem.
źródło
Wypróbowałem tutaj różne odpowiedzi, w tym aktualizację jQuery i stwierdziłem, że to zadziałało. Przetestowałem to na najnowszym 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(); } });
źródło
Dlaczego nie zająć pozycji kursora? Używam sortowalnej wtyczki i naprawiam to tym kodem:
sort: function(e, ui) { $(".ui-sortable-handle.ui-sortable-helper").css({'top':e.pageY}); }
źródło
Użyj
appendTo: "body'
i ustaw pozycję za pomocącursorAt
. U mnie to działa dobrze.$('.js-tire').draggable tolerance: 'fit', appendTo: 'body', cursor: 'move', cursorAt: top: 15, left: 18 helper: (event) -> $('<div class="tire-icon"></div>').append($('<img src="/images/tyre_32_32.png" />')) start: (event, ui) -> if $(event.target).hasClass 'in-use' $('.js-send-to-maintenance-box').addClass 'is-highlighted' else $('.ui-droppable').addClass 'is-highlighted' stop: (event, ui) -> $('.ui-droppable') .removeClass 'is-highlighted' .removeClass 'is-dragover'
źródło
Używam lepkiej nawigacji na górze i pomyślałem, że to właśnie powoduje problem z przewijaniem, który wszyscy wydają się mieć. Wypróbowałem pomysł wszystkich innych za pomocą kursora, próbowałem powstrzymać i nic nie działało Z WYJĄTKIEM zakłócenia przepełnienia HTML w CSS! Niesamowite, jak mały CSS wszystko schrzani. Oto, co zrobiłem i działa jak urok:
html { overflow-x: unset; } body { overflow-x: hidden; }
źródło