web-dev-qa-db-ja.com

jQueryドラッグ可能は、ページのスクロール後にヘルパーを間違った場所に表示します

私が開発している作業計画システムには、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,
});

これを修正するために私ができることはありますか?

78
Alex

これは関連するバグレポートである可能性があり、かなり以前から存在していました。 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;
   }
});
104
DarthJDG

このソリューションは、何かの位置を調整することなく機能します。要素を複製して、絶対位置に配置するだけです。

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

ヘルパーは、ドラッグするDOM要素を返す必要がある関数にすることができます。

43
mordy

これは私のために働いた:

start: function (event, ui) {
   $(this).data("startingScrollTop",window.pageYOffset);
},
drag: function(event,ui){
   var st = parseInt($(this).data("startingScrollTop"));
   ui.position.top -= st;
},
11
Ashraf Fayad

別の回答を書いてすみません。上記の答えのソリューションはどれも私が使用できないため、別の合理的なソリューションを見つける前に、多くのグーグルを行い、イライラするような小さな編集を行いました。

この問題は、親要素のanypositionが 'relative'に設定されている場合に発生するようです。マークアップをシャッフルしてCSSを変更する必要がありましたが、すべての親からこのプロパティを削除することで、すべてのブラウザーで.sortable()を適切に機能させることができました。

7
Joshua Bambrick

このバグは頻繁に発生し、毎回異なる解決策があるようです。上記のどれも、またはインターネットで見つけた他の何かは機能しませんでした。 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で動作しますが、他のブラウザーではまだテストしていません。

7
kazmer

オーバーフローを削除します。

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

そして、それは完全に機能します!

5
Miguel Puig

このバグは 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の問題が解決されるようです(以下のコメント)。

5
Patrick

このバグは修正されていないはずだというのは驚くべきことです。私にとっては、SafariとChrome(つまり、Webkitブラウザー)では問題ですが、IE7/8/9やFirefoxでは問題なく動作します。

!importantの有無にかかわらず、絶対または固定の設定は役に立たないことがわかったため、最終的にドラッグハンドラー関数に行を追加しました。

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

その行をWebkit固有にする必要があると予想していましたが、奇妙なことに、どこでも問題なく機能しました。 (すぐに「いや、実際には他のすべてのブラウザーを台無しにしてしまった」というコメントを期待してください。)

4
Allen

私がやったことは:

$("#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
Pankaj Sharma

私は同じ問題を抱えていて、これはすべて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に感謝します。乾杯!

1
fled

これがすべての場合に機能するかどうかはよくわかりませんが、この回避策は、テストする必要のあるさまざまな状況で作業しました(ここで提供された以前の提案されたソリューションがすべて失敗した場合)

(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年前のバグを最終的に修正できればクールです:/)

1
vor

ドラッグしたアイテムにdisplay: inline-blockを追加することで同じ問題を修正できました

position: relativeを追加しても機能しませんでした(jQueryはドラッグ開始時にposition: absoluteで上書きします)

使用されたjQueryバージョン:

  • jQuery-1.7.2
  • jQuery UI-1.11.4
1
Plamen

これは親でposition:absoluteを使用する必要なしに回避策を行うようです:)

$("body").draggable({
     drag: function(event, ui) { 
         return false; 
     } 
});
1
TomCe

これは、私が読んだ問題についてすべてを適応させた後、私にとってうまくいったことです。

$(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の親または祖先です。

スクロール要素の位置を計算し、移動/ドラッグするたびにヘルパーの位置に追加します。

私がこれに大きな時間を無駄にしたので、それが誰かを助けることを願っています。

1
Rnubi

Firefox 21.0でドラッグ可能なJQueryを使用していますが、同じ問題が発生しています。カーソルは、ヘルパーイメージの上1インチのままです。これは、まだ解決されていないJquery自体の問題だと思います。ドラッグ可能の「cursorAt」プロパティを使用しているこの問題の回避策を見つけました。次のように使用しましたが、要件に応じてこれを変更できます。

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

注:これはすべてのブラウザーに適用されるため、このコードを使用した後、すべてのブラウザーでページをチェックして、正しい左および上の位置を取得してください。

1
impiyush

私は上部に粘着性のナビゲーションを使用しており、それが他の誰もが持っているように見えるスクロールの問題を引き起こしているのだと思った。 cursorAtで他のすべての人のアイデアを試しました。封じ込めを試みましたが、CSSでhtmlオーバーフローを設定解除する以外は何も機能しませんでした。ちょっとしたCSSがすべてを台無しにするのは非常識です。これは私がやったことであり、魅力のように機能します:

html {
  overflow-x: unset;
}

body {
  overflow-x: hidden;
}
0
Altus Nix

ここで、jQueryの更新など、さまざまな回答を試みましたが、これでうまくいくことがわかりました。これを最新のchromeおよびIEでテストしました。これは、UIレイアウトによって異なるソリューションで問題になると思います。

$('{selector}').draggable({
    start: function(event, ui) {
        ui.position.top -= $(document).scrollTop();
    },
    drag: function(event, ui) {
        ui.position.top -= $(document).scrollTop();
    }
});
0
Lee Willis

ドラッグ可能なjQueryUiの使用をやめ、jQueryUIのすべてのくだらないことなく、コードサイズがはるかに小さい jquery.even.drag という優れたプラグインを使用するように移動しました。

Position:fixedを持つコンテナ内でこのプラグインを使用してデモページを作成しました

デモ

この問題が大きいので、これが誰かを助けることを願っています。

0
vsync

つかいます appendTo: "body'およびcursorAtで位置を設定します。これは私には問題ありません。

Example of my icon following the mouse cursor even after scrolling the page

$('.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'
0
Michelle Diniz

カーソル位置を取りませんか?私はソート可能なプラグインを使用していますが、このコードで修正します:

sort: function(e, ui) {
    $(".ui-sortable-handle.ui-sortable-helper").css({'top':e.pageY});
}
0
Aztrozero

Windows 8で特定のIE 10を実行している場合のみ、同様の問題が発生しました。他のすべてのブラウザーは正常に機能しました。cursorAt:{top:0}を削除すると問題が解決しました。

0
nmm