development

jQuery UI 정렬 가능한 스크롤 도우미 요소 오프셋 Firefox 문제

big-blog 2020. 12. 31. 23:18
반응형

jQuery UI 정렬 가능한 스크롤 도우미 요소 오프셋 Firefox 문제


Firefox 3.6, IE7-8에서 jQuery UI 1.7.2 정렬 가능한 목록에 문제가 있습니다. 조금 아래로 스크롤하면 도우미 요소에 마우스 포인터에서 아래로 스크롤 한 것과 동일한 높이의 오프셋이있는 것처럼 보이므로 원래 끌기 시작한 항목을 볼 수 없습니다. 이 문제를 해결하거나 해결하려면 어떻게합니까? 수정 사항이 없다면 정말 좋은 대체 드래그 가능 플러그인은 무엇입니까?

다음은 정렬 가능에 대한 초기화 매개 변수입니다.

$("#sortable").sortable( {placeholder: 'ui-state-highlight'  } );
$("#sortable").disableSelection();

이 문제를 보았고 내 페이지의 포함 div 중 하나에서 CSS 규칙 위치 : 상대를 제거하여 해결할 수있었습니다. 참조 : http://forum.jquery.com/topic/sortable-offset-when-element-is-dragged-and-page-scrolled-down-ff


브라우저 스니핑을 방지하려는 경우 CSS 전용 솔루션은 ul 또는 컨테이너 스타일을 overflow: auto. 방화범을 통해 소스를 보면 jQuery가 예제 에서 수행하는 방식 입니다.


사용 overflow: auto;은 나에게 선택 사항이 아닙니다. sort이벤트 처리기 로이 문제를 해결할 수있었습니다 .

$(...).sortable({
    ...
    sort: function(event, ui) {
        var $target = $(event.target);
        if (!/html|body/i.test($target.offsetParent()[0].tagName)) {
            var top = event.pageY - $target.offsetParent().offset().top - (ui.helper.outerHeight(true) / 2);
            ui.helper.css({'top' : top + 'px'});
        }
    },
    ...
});

완벽하지는 않지만 브라우저 스니핑이 필요하지 않습니다. IE8, Chrome 및 Firefox에서 테스트되었습니다.

편집 : 이것은 jQuery 1.10.0 및 jQuery UI 1.10.3을 사용하고 있습니다.


나는 또한이 문제가 있었고 다음 코드로 수정했습니다.

var wscrolltop = 0;
$sortable_elements.sortable({ 
    start: function(event, ui) {
        wscrolltop = $(window).scrollTop();
    },
    sort: function(event, ui) {                   
        ui.helper.css({'top' : ui.position.top + wscrolltop + 'px'});
    }
});

정렬 가능한 요소로 스크롤하면 여전히 문제가 있음을 발견했습니다. 누군가가 이것에 대한 해결책을 가지고 있습니까?

업데이트 : 수정 사항은 다음과 같습니다.

$sortable_elements.sortable({ 
    connectWith: '#personal-favs ul.fitems',
    sort: function(event, ui) {  
        ui.helper.css({'top' : ui.position.top + $(window).scrollTop() + 'px'});
    }
});

그러나 여전히-목록을 떠나면 정렬 이벤트가 중지되는 것 같습니다.


당신은 또한 이것이 파이어 폭스에만 국한된다는 사실을 고려해야합니다. 여기 제가 사용하고있는 스 니펫이 있습니다. 저는 Harris의 솔루션에서 올바른 방향으로 지시 받았습니다. 정렬 가능한 컨테이너가 상대적으로 배치 된 컨테이너에있을 때 도우미를 사용하지 않고이 문제가 발생했습니다.

  var options = { 
   handle: '.mover', 
   update:updateSorting 
 };
  var userAgent = navigator.userAgent.toLowerCase();
  if(userAgent.match(/firefox/)) {
    options["start"] = function (event, ui) { ui.item.css('margin-top', $(window).scrollTop() ); };
    options["beforeStop"] = function (event, ui) { ui.item.css('margin-top', 0 ); };
  }
  $("#" + list_id+"").sortable(options);
  $("#" + list_id+"").disableSelection();

서버에서이 확인을 수행 한 다음 브라우저에 따라 두 가지 다른 호출을 수행 할 수도 있습니다.


나는 이것에 대한 수정을 알아 냈다.

$( "items" ).sortable({
start: function (event, ui) {
 if( ui.helper !== undefined )
  ui.helper.css('position','absolute').css('margin-top', $(window).scrollTop() );
},
beforeStop: function (event, ui) {
 if( ui.offset !== undefined )
  ui.helper.css('margin-top', 0);
},
placeholder: 'placeholder-class'
});

기본적으로, 브라우저의 현재 scrollTop () 값을 도우미 위치에 추가하려면 정렬 가능의 "시작"이벤트를 수신해야합니다. 그런 다음 항목이 공식적으로 표시되기 전에 해당 오프셋을 제거하려면 정렬 가능의 "beforeStop"이벤트를 수신해야합니다. 새 위치의 목록에 다시 배치됩니다.

누군가에게 도움이 되었기를 바랍니다!


내 사이트에서 스크롤바를 강제로 사용하므로이 스크롤 가능 오프셋 문제가 html { overflow-y: scroll }내 CSS에 있기 때문에 발생합니다 .

스크롤 가능을 켜고 끌 때 다음을 사용하여 주변을 둘러 보았습니다. IE8, FF12 및 Chrome에서만 테스트했습니다 ...

  turnSortingOnOff:function(e) {
    e.preventDefault();

    if (stopOrdering()) {
      // get rid of the hacky css on the html element
      $('html').css({ 'overflow-y': '' });
      $('html').css({ 'margin-right': '' });

      elmt.sortable('disable');
    }
    else if (startOrdering()) {
      // if the body is smaller than the window
      // then there aren't any scrollbars
      // in which case, add a right hand margin of 16px
      // to the html to prevent the site wobbling
      if ($('body').outerHeight() <= $(window).height()) {
        $('html').css({ 'margin-right': 16 });
      }

      // then override the { overflow-y: scroll }
      // in the css by setting it to a nice, safe inherit
      $('html').css({ 'overflow-y': 'inherit' });

      elmt.sortable('enable');
    }
  }

분명히 방탄이 아닙니다. 정렬하는 동안 문서 크기가 변경되면 다른 작업을 수행해야합니다. 그러나 내 경험상 그러한 상황에서는 덜 이상해 보입니다.


새로운 jQuery / jQuery UI 버전을 사용하여 "수정"했습니다.

  • jQuery 1.8.0
  • jQuery UI 1.8.23

설정 overflow: auto하면 Firefox가 포인터 아래에있는 요소로 드래그를 시작하지만 자동 스크롤이 제대로 작동하지 않습니다. 스크롤이 필요할만큼 창을 작게 만들면 jQuery Sortable 예제에서 바로 확인할 수 있습니다.

나는 overflow: scrollhtml 태그를 가지고 있었지만 그것을 제거하고 (내 생각에) 모든 상대 포함 요소가 문제를 완전히 해결하지 못했습니다 (즉, 드래그가 올바르게 시작되고 자동 스크롤이 작동 함을 의미합니다). 또한 _findRelativeOffset에 대한 모질라 스니핑 패치를 시도했지만 (그것이 그랬다고 생각합니다) 도움이되지 않았습니다.

내 사용 사례에 도움이 helper: 'clone'된 것은 드래그 가능한 생성자에서 클론으로 드래그하는 것 입니다. 클론이없는 것처럼 보이게하기 위해 가시성을 숨김으로 설정 한 다음 다시 되 돌리는 시작 및 중지 메서드를 추가했습니다.

위에서 언급 했겠지만 아직 포인트가 없습니다.


같은 문제가있었습니다. 제 경우에는 "overflow : auto"-fix를 사용할 수 없었습니다. 그래서 이것이 제가 한 일입니다.

var pos_fixed = 1;        // switch variable (the fix should only be fired ones)
$('.drag').draggable({
 start: function(event, ui){
  pos_fixed = 0;            // we're about to start, set to not fixed yet
 },
 drag: function(event, ui){
  if(pos_fixed == 0){       // check if the fix hasn't been fired for this instance yet
   var help_pos = $(ui.helper).offset().top, // get helpers offset
   targ_pos = $(event.target).offset().top,  // get targets(the dragged elements) offset
   marg = targ_pos-help_pos; // calculate the margin the helper has to have to put it on the same y-position as our target
   $(ui.helper).css('margin-top', marg); // put our helper on the same y-position as the target
   pos_fixed = 1;            // we've fixed it, we don't want it to fire again
  }
 }
});

The fix doesn't care about what browser you are using. It will always make sure that the helper has the same y-offset as the target when the drag starts.


For future readers with this problem. I upgraded from jqueryui 1.8 to 1.10.3 and the problem was solved with no css fixes.

http://jqueryui.com/

I also upgraded from jquery 1.8 to 1.10.2

http://jquery.com/


For future readers I ran into a similar problem where the helper element has an offset when dragging inside the scrolled div of a bootstrap dialog. When releasing the dragged object, the animation sends the dragged helper element towards it's new position without considering the scrolled portion of the page, which gives a confusing feedback to users.

In order to keep things working with position:relative and overflow-y:auto in the dialog container, my solution was

1- Add the scrollTop() offset to the margin-top on the helper object in the sort start event;

2- remove the margin-top in the beforeStop event

This fixed the animation from being off after draging, but the helper object is pushed below the cursor while dragging in the scrolled portion in the page. The last fix is

3- Calculate and set the top property of the helper object while dragging (using the sort event) relative to the pointer and the container offset.

$(...).sortable({
...
start: function (event, ui) {  
    ui.helper.css('margin-top', $("#mybootstrap-dialog").scrollTop()); 
},
beforeStop: function (event, ui){ 
    ui.helper.css('margin-top',0); 
},
sort: function(event, ui) {
    var top = event.clientY - $('#my-sortable-ul').offset().top  -  $("#mybootstrap-dialog").scrollTop();
    ui.helper.css({'top' : top + 'px'});
    }
},
...

});

Help this helps


To summarize your efforts and provide a completed solution. The following seemed to work for Chrome 40+ and Firefox 30+

var isFirefox = /firefox/.test(navigator.userAgent.toLowerCase());
$('#target').sortable({
    connectWith: '#target-holder .elements',
    handle: ".element-header",
    start: function(ev, ui) {
        if( isFirefox ) {
            ui.item.css('margin-top', $(window).scrollTop() );
        }
    },
    sort: function(ev, ui) {
        if( isFirefox) {
            ui.helper.css({'top' : ui.position.top - $(window).scrollTop() + 'px'});
        } else {
            ui.helper.css({'top' : ui.position.top + $(window).scrollTop() + 'px'});
        }
    },
    beforeStop: function (ev, ui) {
        if( isFirefox ) {
            ui.item.css('margin-top', 0 );
        }
    }
});

My solution: ".sortable" to add the "position: relative"

$(".sortable").sortable({
      sort: function(event, ui) {
           ui.position.top = ui.position.top + $(window).scrollTop();
      },
});

PS used jQuery UI 1.12.0 and jQuery 2.2.4


sort: function(e, ui){
        var tempVariable = $(ui.item.get(0));
        tempVariable.css('top', (e.clientY)-(tempVariable.css("height").replace("px", "")));
    }

ReferenceURL : https://stackoverflow.com/questions/2451528/jquery-ui-sortable-scroll-helper-element-offset-firefox-issue

반응형