your programing

jQuery draggable이 페이지 스크롤 후 잘못된 위치에 도우미를 표시합니다.

lovepro 2020. 10. 11. 11:04
반응형

jQuery draggable이 페이지 스크롤 후 잘못된 위치에 도우미를 표시합니다.


개발중인 작업 계획 시스템에 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;
   }
});

이 솔루션은 위치를 조정하지 않고 작동합니다. 요소를 복제하고 절대 위치를 지정하기 만하면됩니다.

$(".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;
},

다른 답변을 써서 죄송합니다. 위 답변의 솔루션 중 어느 것도 사용할 수 없으므로 다른 합리적인 솔루션을 찾기 전에 많은 인터넷 검색을 수행하고 많은 실망스러운 사소한 편집을 수행했습니다.

이 문제는 때마다 발생하는 것 같습니다 어떤 부모 요소가있다 position'상대'로 설정. 마크 업을 다시 섞고 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 버전을 기다리는 것입니다 .

편집 : 이 수정 사항은 이제 버전 1.11까지 삭제되지 않는 http://bugs.jqueryui.com/ticket/9315의 일부일 수 있습니다 . 위의 링크 된 소스 제어 버전의 jQuery를 사용하면 나와 @Scott Alexander (아래 주석)의 문제가 해결되는 것 같습니다.


이 버그가 너무 오래 수정되지 않았어야했다는 것이 놀랍습니다. 나에게는 Safari와 Chrome (예 : 웹킷 브라우저)에서는 문제가되지만 IE7 / 8 / 9 나 Firefox에서는 문제가되지 않으며 모두 잘 작동합니다.

! important 여부에 관계없이 절대 또는 고정 설정이 도움이되지 않았으므로 결국 드래그 핸들러 함수에 한 줄을 추가했습니다.

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

나는 그 라인을 웹킷에 특화시킬 필요가있을 것으로 예상했지만 호기심이 모든 곳에서 잘 작동했습니다. (곧 '아니요, 실제로 다른 모든 브라우저를 엉망으로 만들었습니다'라고 말하는 댓글을 기대하십시오.)


내가 한 것은 :

$("#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 트래커에 제출하여 그들이 그것에 대해 어떻게 생각하는지 확인했습니다. 그 4 년 된 버그가 마침내 수정 될 수 있다면 멋질 것입니다 : /)


Firefox 21.0에서 JQuery draggable을 사용하고 있는데 같은 문제가 있습니다. 커서는 도우미 이미지에서 1 인치 위에 있습니다. 나는 이것이 아직 해결되지 않은 Jquery 자체의 문제라고 생각합니다. draggable의 "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는 overflow : auto가있는 상위 또는 조상입니다.

스크롤링 요소의 위치를 ​​계산하고 이동 / 드래그 할 때마다 도우미 위치에 추가합니다.

내가 이것에 많은 시간을 낭비했기 때문에 누군가에게 도움이되기를 바랍니다.


이것은 부모에서 position : absolute를 사용할 필요없이 해결 방법을 수행하는 것 같습니다. :)

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

display: inline-block드래그 한 항목에 추가하는 것과 동일한 문제를 해결했습니다.

추가 position: relative가 작동하지 않았습니다 (jQuery position: absolute는 드래그 시작시 재정의 )

사용 된 jQuery 버전 :

  • jQuery-1.7.2
  • jQuery UI-1.11.4

나는 똑같은 문제가 있었고이 모든 것이 위치가 고정 된 부트 스트랩 navbar "navbar-fixed-top"클래스로 <body>인해 <html>상단 보다 60px 아래 로 이동한다는 것을 알았습니다 . 따라서 내 사이트에서 드래그 가능한 양식을 이동할 때 커서가 양식 위에 60px로 나타났습니다.

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);

이제 부트 스트랩 navbar를 사용하여 사이트에서 드래그 가능한 요소 / 양식을 초기화 할 때 :

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

물론 자신의 사이트에 따라 올바른 yOffset을 결정하기 위해 실험해야합니다.

어쨌든 나에게 올바른 방향을 알려준 DarthJDG에게 감사드립니다. 건배!


나는 jQueryUi draggable 사용을 그만두고 jQueryUI가 가진 모든 쓰레기없이 훨씬 작은 코드 크기 인 jquery.even.drag 라는 더 나은 플러그인을 사용하기 위해 이동했습니다 .

위치가있는 컨테이너 내부에서이 플러그인을 사용하여 데모 페이지를 만들었습니다.

데모

이 문제가 크기 때문에 누군가에게 도움이되기를 바랍니다.


Windows 8에서 실행되는 특정 IE 10에서만 비슷한 문제가 발생했습니다. 다른 모든 브라우저는 정상적으로 작동했습니다. cursorAt : {top : 0}을 제거하면 문제가 해결되었습니다.


여기에서 jQuery 업데이트를 포함하여 다양한 답변을 시도한 결과 이것이 저에게 효과적이라는 것을 알았습니다. 나는 이것을 최신 크롬과 IE에서 테스트했습니다. UI 레이아웃에 따라 다른 솔루션에 문제가 될 것 같습니다.

$('{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. 이것은 나에게 잘 작동합니다.

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'

I'm using a sticky nav at the top and thought that was what was causing the scroll issue everyone else seems to be having. I tried everyone else's idea with cursorAt, I tried containment, and nothing worked EXCEPT unsetting my html overflow in the CSS! Insane how a little CSS will screw everything up. This is what I did and it works like a charm:

html {
  overflow-x: unset;
}

body {
  overflow-x: hidden;
}

참고URL : https://stackoverflow.com/questions/5791886/jquery-draggable-shows-helper-in-wrong-place-after-page-scrolled

반응형