Я использую jQuery с возможностью перетаскивания и удаления для разрабатываемой мной системы планирования работы. Пользователи перетаскивают задания на другой день или другого пользователя, а затем данные обновляются с помощью вызова ajax.
Все работает нормально, кроме тех случаев, когда я прокручиваю главную страницу вниз (задания отображаются в большом планировщике на неделю, который выходит за пределы нижней части окна браузера). Если я попытаюсь перетащить сюда перетаскиваемый элемент, он появится над курсором мыши на то же количество пикселей, что и я прокручиваю вниз. Состояние наведения все еще работает нормально, и функциональность работает, но выглядит неправильно.
Я использую jQuery 1.6.0 и jQuery UI 1.8.12.
Я уверен, что мне нужно добавить функцию смещения, но я не знаю, где ее применить, и есть ли способ лучше. Вот мой .draggable()
код инициализации:
$('.job').draggable({
zIndex: 20,
revert: 'invalid',
helper: 'original',
distance: 30,
refreshPositions: true,
});
Есть идеи, что я могу сделать, чтобы это исправить?
Ответы:
Это может быть связанный отчет об ошибке, он существует довольно давно: http://bugs.jqueryui.com/ticket/3740
Кажется, это происходит во всех протестированных мной браузерах (Chrome, FF4, IE9). Есть несколько способов обойти эту проблему:
1. Используйте
position:absolute;
в своем css. Абсолютно позиционированные элементы не пострадали.2. Убедитесь, что родительский элемент (событие, если это тело)
overflow:auto;
установлен. Мой тест показал, что это решение исправляет положение, но отключает функцию автопрокрутки. Вы по-прежнему можете выполнять прокрутку с помощью колесика мыши или клавиш со стрелками.3. Примените исправление, предложенное в приведенном выше отчете об ошибке, вручную и тщательно проверьте, не вызывает ли оно других проблем.
4. Дождитесь официального исправления. Планируется, что появится jQuery UI 1.9, хотя в прошлом это несколько раз откладывалось.
5. Если вы уверены, что это происходит в каждом браузере, вы можете поместить эти хаки в события затронутых перетаскиваемых объектов, чтобы исправить вычисления. Тем не менее, нужно протестировать множество разных браузеров, поэтому использовать его следует только в крайнем случае:
$('.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; } });
источник
helper: "clone"
. bugs.jqueryui.com/ticket/9315 Уровень блокатор , вырезка выше основных. tj.vantoll говорит: «6 перетаскиваемых исправлений, появившихся в 1.10.3, могут быть подозрительными». Самый простойЭто решение работает без изменения позиционирования чего-либо, вы просто клонируете элемент и делаете его абсолютно позиционированным.
$(".sidebar_container").sortable({ .. helper: function(event, ui){ var $clone = $(ui).clone(); $clone .css('position','absolute'); return $clone.get(0); }, ... });
Помощником может быть функция, которая должна возвращать элемент DOM для перетаскивания.
источник
Это сработало для меня:
start: function (event, ui) { $(this).data("startingScrollTop",window.pageYOffset); }, drag: function(event,ui){ var st = parseInt($(this).data("startingScrollTop")); ui.position.top -= st; },
источник
"1.11.0"
Извините, что написал еще один ответ. Поскольку ни одно из решений в приведенном выше ответе не могло быть использовано мной, я много гуглил и сделал много разочаровывающих мелких правок, прежде чем найти другое разумное решение.
Эта проблема возникает всякий раз, когда для любого из родительских элементов
position
установлено значение «относительный». Мне пришлось перетасовать разметку и изменить свой CSS, но, удалив это свойство у всех родителей, я смог.sortable()
нормально работать во всех браузерах.источник
position: relative;
в любом родительском элементе.position: relative;
которым пришлось удалить ... родительские элементы между перетаскиваемым и телом, похоже, не создают здесь проблем ..Похоже, что эта ошибка возникает очень часто, и каждый раз появляется новое решение. Ничего из вышеперечисленного или что-то еще, что я нашел в Интернете, не помогло. Я использую jQuery 1.9.1 и JQuery UI 1.10.3. Вот как я это исправил:
$(".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(); } });
Работает в FF, IE, Chrome, в других браузерах еще не тестировал.
источник
Удаляю перелив:
html {overflow-y: scroll; background: #fff;}
И работает отлично!
источник
Эта ошибка была перенесена на http://bugs.jqueryui.com/ticket/6817 и примерно 5 дней назад (16 декабря 2013 г. или около того), похоже, наконец-то исправлена. Сейчас предлагается использовать последнюю
версиюразработки из http://code.jquery.com/ui/jquery-ui-git.js или дождатьсяверсии 1.10.4, которая должна содержать это исправление.Изменить: похоже, это исправление теперь может быть частью http://bugs.jqueryui.com/ticket/9315, которое не планируется удалять до версии 1.11. Использование указанной выше версии jQuery для управления исходным кодом, похоже, решает проблему для меня и @Scott Alexander (комментарий ниже).
источник
Замечательно, что эту ошибку так долго не исправляли. Для меня это проблема Safari и Chrome (то есть браузеров webkit), но не IE7 / 8/9 или Firefox, которые все работают нормально.
Я обнаружил, что установка absolute или fixed, с! Important или без него не помогает, поэтому в конце я добавил строку в свою функцию обработчика перетаскивания:
ui.position.top += $( 'body' ).scrollTop();
Я ожидал, что мне нужно будет сделать эту строку специфичной для webkit, но, как ни странно, она везде работала нормально. (Ожидайте от меня комментария в ближайшее время: «Э, нет, на самом деле это испортило все остальные браузеры».)
источник
я сделал следующее:
$("#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); } });
источник
Я не совсем уверен, что это сработает в каждом случае, но это обходное решение, которое я только что применил для меня во всех различных ситуациях, которые мне приходилось тестировать (и где предыдущие предложенные решения, приведенные здесь и в других местах, не дали результата)
(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));
(Я отправил его в трекер jQuery.ui, чтобы узнать, что они думают об этом ... было бы круто, если бы эту ошибку четырехлетней давности можно было наконец исправить: /)
источник
Я использую перетаскиваемый JQuery в Firefox 21.0, и у меня такая же проблема. Курсор остается на дюйм выше вспомогательного изображения. Я думаю, что это проблема самого JQuery, которая до сих пор не решена. Я нашел обходной путь к этой проблеме, который использует свойство "cursorAt" перетаскиваемого объекта. Я использовал его следующим образом, но его можно изменить по своему усмотрению.
$('.dragme').draggable({ helper: 'clone', cursor: 'move', cursorAt: {left: 50, top: 80} });
Примечание. Это будет применимо для всех браузеров, поэтому после использования этого кода проверьте свою страницу во всех браузерах, чтобы получить правильное левое и верхнее положение.
источник
Это то, что у меня сработало после адаптации всего, что я прочитал по проблеме.
$(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 - это родитель или предок с переполнением: auto;
Определяет положение элемента прокрутки и добавляет к положению помощника при каждом его перемещении / перетаскивании.
Надеюсь, это кому-то поможет, так как я потратил на это много времени.
источник
Кажется, это обходной путь без необходимости использовать position: absolute в родительском элементе :)
$("body").draggable({ drag: function(event, ui) { return false; } });
источник
Мне удалось исправить ту же проблему с добавлением
display: inline-block
к перетаскиваемым элементамДобавление
position: relative
НЕ сработало для меня (jQuery отменяет его приposition: absolute
запуске перетаскивания)Используемые версии jQuery:
источник
position: relative
могло сработать, если вы переместили его в элемент контейнера более высокого уровня. Я знаю, что сейчас это не помогает, но только для справки и, возможно, для будущего проблемного разработчика.У меня была та же проблема, и я обнаружил, что все это произошло из-за класса «navbar-fixed-top» панели навигации начальной загрузки с фиксированным положением, который перемещается на
<body>
60 пикселей ниже, чем<html>
верхний. Поэтому, когда я перемещал перетаскиваемые формы на своем сайте, курсор появлялся на 60 пикселей поверх формы.Вы можете видеть, что в инструменте отладки Chrome в интерфейсе Elements щелкните значок
<body>
тег, и вы увидите зазор между верхом и телом.Поскольку я использую эту панель навигации во всех своих приложениях и не хочу изменять свой инициализирующий вызов для перетаскивания (в соответствии с процедурой DarthJDG) для каждой формы. Я решил таким образом расширить перетаскиваемый виджет и просто добавить yOffset в мою перетаскиваемую инициализацию.
(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);
Теперь, когда я инициализирую перетаскиваемый элемент / форму на сайте с помощью начальной панели навигации:
// Make the edit forms draggable $("#org_account_pop").draggable({handle:" .drag_handle", yOffset: 60});
Конечно, вам придется поэкспериментировать, чтобы определить правильное значение yOffset для вашего собственного сайта.
В любом случае спасибо DarthJDG, который указал мне правильное направление. Ура!
источник
Я перестал использовать jQueryUi с возможностью перетаскивания и перешел на более совершенный плагин под названием jquery.even.drag. , с гораздо меньшим размером кода, без всего того дерьма, которое есть у jQueryUI.
Я сделал демонстрационную страницу, используя этот плагин внутри контейнера с position: fixed.
Демо
Надеюсь, это кому-то поможет, потому что проблема БОЛЬШАЯ.
источник
У меня была аналогичная проблема, только с определенным IE 10, работающим в Windows 8. Все остальные браузеры работали нормально. Удаление cursorAt: {top: 0} решило проблему.
источник
Я пробовал здесь разные ответы, включая обновление jQuery, и обнаружил, что это сработало для меня. Я тестировал это на последних версиях Chrome и IE. Я предполагаю, что это будет проблема с разными решениями в зависимости от вашего макета пользовательского интерфейса.
$('{selector}').draggable({ start: function(event, ui) { ui.position.top -= $(document).scrollTop(); }, drag: function(event, ui) { ui.position.top -= $(document).scrollTop(); } });
источник
Почему бы не занять позицию курсора? Я использую сортируемый плагин и исправляю его с помощью этого кода:
sort: function(e, ui) { $(".ui-sortable-handle.ui-sortable-helper").css({'top':e.pageY}); }
источник
Используйте
appendTo: "body'
и установите положение с помощьюcursorAt
. Это прекрасно работает со мной.$('.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'
источник
Я использую липкую навигацию вверху и думал, что это было причиной проблемы с прокруткой, которая, похоже, есть у всех остальных. Я попробовал идею других с cursorAt, я попробовал сдерживание, и ничего не сработало, ЗА ИСКЛЮЧЕНИЕМ отключения моего переполнения html в CSS! Безумие, как немного CSS все испортит. Это то, что я сделал, и это работает как шарм:
html { overflow-x: unset; } body { overflow-x: hidden; }
источник