programing

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

topblog 2023. 10. 30. 20:26
반응형

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

저는 제가 개발 중인 작업 계획 시스템에 jQuery draggabledropable을 사용하고 있습니다.사용자는 작업을 다른 요일이나 사용자에게 끌어다 놓은 다음 데이터를 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;set. 테스트 결과 이 솔루션은 위치를 고정하지만 자동 스크롤 기능을 비활성화합니다.마우스 휠이나 화살표 키를 사용하여 스크롤할 수도 있습니다.

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;
},

다른 답변을 써서 죄송합니다.위 답변의 어떤 해결책도 제가 사용할 수 없었기 때문에, 저는 다른 합리적인 해결책을 찾기 전에 구글링을 많이 했고 여러 번 약간의 좌절감을 주는 편집을 했습니다.

이 문제는 상위 구성 요소 중 하나가 다음을 수행할 때마다 발생하는 것으로 보입니다.positionrelative'로 설정합니다.마크업을 변경하고 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(아래 코멘트)의 문제가 해결되는 것 같습니다.

이 버그가 그렇게 오랫동안 고쳐지지 않았다는 것은 놀라운 일인 것 같습니다.저에게는 사파리와 크롬(즉, 웹킷 브라우저)에서는 문제가 되지만 IE7/8/9나 파이어폭스에서는 문제가 되지 않습니다.

!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살 벌레가 마침내 수정될 수 있다면 멋질 것입니다 :/ )

파이어폭스 21.0에서 JQuery draggable을 사용하고 있는데 같은 문제가 발생하고 있습니다.커서는 도우미 이미지보다 1인치 위에 있습니다.아직 해결되지 않은 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();
  },
  ...
}); 

*Scrolls가 overflow:auto를 가진 상위 또는 상위입니다.

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

그게 누군가에게 도움이 되길 바라요, 제가 이 일에 많은 시간을 낭비했기 때문입니다.

이렇게 하면 부모님의 절대적인 위치를 사용할 필요 없이 해결할 수 있을 것 같습니다. :)

$("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-fixed-top" 클래스 때문이라는 것을 알았습니다.<body>보다 60px 낮음<html> 내 한 폼을 할 때 top 그래서 내 사이트에서 드래그 가능한 폼을 이동할 때 폼 위에 커서가 60px로 나타났습니다.

Chrome 디버깅 툴의 Elements 인터페이스에서 다음을 클릭하는 것을 볼 수 있습니다.<body>태그를 하면 상의와 몸체 사이의 간격이 보일 것입니다.

애플리케이션 전체에서 이 탐색 모음을 사용하고 있고 각 양식에 대한 초기화 호출을 드래그(DarthJDG의 절차에 따라)하도록 수정하고 싶지 않았기 때문입니다.드래그 가능 위젯을 이런 식으로 확장하고 드래그 가능 초기화에 오프셋을 간단히 추가하기로 결정했습니다.

(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을 결정하기 위해 실험을 해야 할 것입니다.

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

상단에 끈적거리는 내비게이션을 사용하고 있는데 그것이 다른 사람들이 가지고 있는 스크롤 문제의 원인이라고 생각했습니다.cursorAt로 다른 사람들의 아이디어를 시도했지만 containment를 시도했지만 CSS에서 html 오버플로 설정을 해제하는 것 외에는 아무것도 작동하지 않았습니다!작은 CSS가 모든 것을 망치는 것은 미친 짓입니다.이것이 제가 한 일이고 이것은 매력처럼 작용합니다.

html {
  overflow-x: unset;
}

body {
  overflow-x: hidden;
}

저는 jQueryUi draggable 사용을 그만두고 jQuery.even.drag라는 더 나은 플러그인을 사용하기 위해 옮겼습니다. jQueryUi가 가지고 있는 온갖 쓰레기 같은 코드 없이 훨씬 더 작은 코드 크기입니다.

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

데모

이것이 누군가에게 도움이 되기를 바랍니다. 왜냐하면 이 문제가 크기 때문입니다.

윈도우 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'

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

반응형