私が開発している作業計画システムには、jQuery draggable および droppable を使用しています。ユーザーはジョブを別の日またはユーザーにドラッグすると、データは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/374
私がテストしたすべてのブラウザー(Chrome、FF4、IE9)で発生するようです。この問題を回避する方法はいくつかあります。
1。 cssでposition:absolute;
を使用します。絶対に配置された要素は影響を受けないようです。
2。親要素(本体の場合はイベント)にoverflow:auto;
が設定されていることを確認してください。私のテストでは、このソリューションは位置を修正しますが、自動スクロール機能を無効にすることが示されました。マウスホイールまたは矢印キーを使用して引き続きスクロールできます。
。上記のバグレポートで提案された修正を手動で適用し、それが他の問題を引き起こす場合は徹底的にテストします。
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;
}
});
このソリューションは、何かの位置を調整することなく機能します。要素を複製して、絶対位置に配置するだけです。
$(".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;
},
別の回答を書いてすみません。上記の答えのソリューションはどれも私が使用できないため、別の合理的なソリューションを見つける前に、多くのグーグルを行い、イライラするような小さな編集を行いました。
この問題は、親要素のanyがposition
が 'relative'に設定されている場合に発生するようです。マークアップをシャッフルしてCSSを変更する必要がありましたが、すべての親からこのプロパティを削除することで、すべてのブラウザーで.sortable()
を適切に機能させることができました。
このバグは頻繁に発生し、毎回異なる解決策があるようです。上記のどれも、またはインターネットで見つけた他の何かは機能しませんでした。 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日前(2013年12月16日頃)にようやく修正されたようです。現時点での提案は、 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では問題なく動作します。
!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);
}
});
私は同じ問題を抱えていて、これはすべてbootstrap navbar "navbar-fixed-top"クラスの位置が固定されているため、_<body>
60px未満<html>
上。そのため、サイトでドラッグ可能なフォームを移動すると、カーソルがフォームの上に60ピクセルで表示されました。
ChromeデバッグツールのElementsインターフェースで、<body>
タグを使用すると、上部と本体の間に隙間ができます。
私はアプリケーション全体でこのnavbarを使用しており、各フォームのドラッグの初期化呼び出し(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);
bootstrap navbarを使用して、サイトのドラッグ可能な要素/フォームを初期化するとき:
// Make the edit forms draggable
$("#org_account_pop").draggable({handle:" .drag_handle", yOffset: 60});
もちろん、自分のサイトごとに正しいyOffsetを決定するために実験する必要があります。
とにかく、私に正しい方向を示してくれたDarthJDGに感謝します。乾杯!
これがすべての場合に機能するかどうかはよくわかりませんが、この回避策は、テストする必要のあるさまざまな状況で作業しました(ここで提供された以前の提案されたソリューションがすべて失敗した場合)
(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トラッカーにそれを提出して、彼らがそれについてどう思うかを確認しました。その4年前のバグを最終的に修正できればクールです:/)
ドラッグしたアイテムにdisplay: inline-block
を追加することで同じ問題を修正できました
position: relative
を追加しても機能しませんでした(jQueryはドラッグ開始時にposition: absolute
で上書きします)
使用されたjQueryバージョン:
これは親でposition:absoluteを使用する必要なしに回避策を行うようです:)
$("body").draggable({
drag: function(event, ui) {
return false;
}
});
これは、私が読んだ問題についてすべてを適応させた後、私にとってうまくいったことです。
$(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は、overflow:autoの親または祖先です。
スクロール要素の位置を計算し、移動/ドラッグするたびにヘルパーの位置に追加します。
私がこれに大きな時間を無駄にしたので、それが誰かを助けることを願っています。
Firefox 21.0でドラッグ可能なJQueryを使用していますが、同じ問題が発生しています。カーソルは、ヘルパーイメージの上1インチのままです。これは、まだ解決されていないJquery自体の問題だと思います。ドラッグ可能の「cursorAt」プロパティを使用しているこの問題の回避策を見つけました。次のように使用しましたが、要件に応じてこれを変更できます。
$('.dragme').draggable({
helper: 'clone',
cursor: 'move',
cursorAt: {left: 50, top: 80}
});
注:これはすべてのブラウザーに適用されるため、このコードを使用した後、すべてのブラウザーでページをチェックして、正しい左および上の位置を取得してください。
私は上部に粘着性のナビゲーションを使用しており、それが他の誰もが持っているように見えるスクロールの問題を引き起こしているのだと思った。 cursorAtで他のすべての人のアイデアを試しました。封じ込めを試みましたが、CSSでhtmlオーバーフローを設定解除する以外は何も機能しませんでした。ちょっとしたCSSがすべてを台無しにするのは非常識です。これは私がやったことであり、魅力のように機能します:
html {
overflow-x: unset;
}
body {
overflow-x: hidden;
}
ここで、jQueryの更新など、さまざまな回答を試みましたが、これでうまくいくことがわかりました。これを最新のchromeおよびIEでテストしました。これは、UIレイアウトによって異なるソリューションで問題になると思います。
$('{selector}').draggable({
start: function(event, ui) {
ui.position.top -= $(document).scrollTop();
},
drag: function(event, ui) {
ui.position.top -= $(document).scrollTop();
}
});
ドラッグ可能なjQueryUiの使用をやめ、jQueryUIのすべてのくだらないことなく、コードサイズがはるかに小さい jquery.even.drag という優れたプラグインを使用するように移動しました。
Position:fixedを持つコンテナ内でこのプラグインを使用してデモページを作成しました
デモ (
この問題が大きいので、これが誰かを助けることを願っています。
つかいます 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'
カーソル位置を取りませんか?私はソート可能なプラグインを使用していますが、このコードで修正します:
sort: function(e, ui) {
$(".ui-sortable-handle.ui-sortable-helper").css({'top':e.pageY});
}
Windows 8で特定のIE 10を実行している場合のみ、同様の問題が発生しました。他のすべてのブラウザーは正常に機能しました。cursorAt:{top:0}を削除すると問題が解決しました。