[jquery] 오버플로 된 Div 내의 요소로 어떻게 스크롤합니까?

한 번에 5 개만 표시 할 수있는 div 안에 20 개의 목록 항목이 있습니다. 항목 # 10으로 스크롤 한 다음 항목 # 20으로 스크롤하는 좋은 방법은 무엇입니까? 모든 항목의 높이를 알고 있습니다.

scrollTo플러그인은이 작업을 수행하지만, 소스 정말 그것으로 점점없이 이해하기 매우 쉬운 일이 아니다. 이 플러그인을 사용하고 싶지 않습니다.

이 전 2 개 요소를받는 함수가 있다고 가정 해 봅시다 $parentDiv, $innerListItem, 어느 쪽 $innerListItem.offset().top$innerListItem.positon().top나에게 $ parentDiv에 대한 올바른 scrollTop을 제공합니다.



답변

$innerListItem.position().top받는 실제 상대적 .scrollTop()최초 위치 지정된 조상. 따라서 올바른 $parentDiv.scrollTop()값 을 계산하는 방법 $parentDiv은 위치가 올바른지 확인하는 것 입니다. 명시 적이 없으면를 position사용하십시오 position: relative. 요소 $innerListItem와 모든 조상 $parentDiv은 명시적인 위치를 가질 필요가 없습니다. 이제 $innerListItemwith (으)로 스크롤 할 수 있습니다 .

// Scroll to the top
$parentDiv.scrollTop($parentDiv.scrollTop() + $innerListItem.position().top);

// Scroll to the center
$parentDiv.scrollTop($parentDiv.scrollTop() + $innerListItem.position().top
    - $parentDiv.height()/2 + $innerListItem.height()/2);


답변

이것은 내 자신의 플러그인입니다 (요소를 목록 맨 위에 배치합니다. 특히 overflow-y : auto.와 함께 작동하지 않을 수 있습니다 overflow-x!)

참고 : elem페이지를 스크롤 할 요소의 HTML 선택기입니다. : 추천 jQuery를, 지원 건 #myid, div.myclass, $(jquery object), [DOM 객체, 등등

jQuery.fn.scrollTo = function(elem, speed) {
    $(this).animate({
        scrollTop:  $(this).scrollTop() - $(this).offset().top + $(elem).offset().top
    }, speed == undefined ? 1000 : speed);
    return this;
};

애니메이션이 필요하지 않은 경우 다음을 사용하십시오.

jQuery.fn.scrollTo = function(elem) {
    $(this).scrollTop($(this).scrollTop() - $(this).offset().top + $(elem).offset().top);
    return this;
};

사용하는 방법:

$("#overflow_div").scrollTo("#innerItem");
$("#overflow_div").scrollTo("#innerItem", 2000); //custom animation speed 

참고 : #innerItem내부 어디에나있을 수 있습니다 #overflow_div. 직접적인 아이 일 필요는 없습니다.

Firefox (23) 및 Chrome (28)에서 테스트되었습니다.

전체 페이지를 스크롤하려면 이 질문을 확인 하십시오 .


답변

overflow div가 페이지 상단에 없을 수도 있다는 사실을 설명하기 위해 Glenn Moss의 답변을 조정했습니다.

parentDiv.scrollTop(parentDiv.scrollTop() + (innerListItem.position().top - parentDiv.position().top) - (parentDiv.height()/2) + (innerListItem.height()/2)  )

반응 형 템플릿이있는 Google지도 응용 프로그램에서 이것을 사용하고있었습니다. 800px 이상의 해상도에서 목록은지도의 왼쪽에있었습니다. 해상도 <800에서 목록은지도 아래에있었습니다.


답변

위의 답변은 내부 요소가 오버플로 요소 내부에 있어도 오버플로 요소의 맨 위에 배치합니다. 요소가 보이지 않는 경우 스크롤 위치를 변경하지 않도록 수정하지 않았습니다.

jQuery.fn.scrollTo = function(elem, speed) {
    var $this = jQuery(this);
    var $this_top = $this.offset().top;
    var $this_bottom = $this_top + $this.height();
    var $elem = jQuery(elem);
    var $elem_top = $elem.offset().top;
    var $elem_bottom = $elem_top + $elem.height();

    if ($elem_top > $this_top && $elem_bottom < $this_bottom) {
        // in view so don't do anything
        return;
    }
    var new_scroll_top;
    if ($elem_top < $this_top) {
        new_scroll_top = {scrollTop: $this.scrollTop() - $this_top + $elem_top};
    } else {
        new_scroll_top = {scrollTop: $elem_bottom - $this_bottom + $this.scrollTop()};
    }
    $this.animate(new_scroll_top, speed === undefined ? 100 : speed);
    return this;
};


답변

나는 내 인생을 더 쉽게하기 위해이 두 가지 기능을 작성합니다.

function scrollToTop(elem, parent, speed) {
    var scrollOffset = parent.scrollTop() + elem.offset().top;
    parent.animate({scrollTop:scrollOffset}, speed);
    // parent.scrollTop(scrollOffset, speed);
}

function scrollToCenter(elem, parent, speed) {
    var elOffset = elem.offset().top;
    var elHeight = elem.height();
    var parentViewTop = parent.offset().top;
    var parentHeight = parent.innerHeight();
    var offset;

    if (elHeight >= parentHeight) {
        offset = elOffset;
    } else {
        margin = (parentHeight - elHeight)/2;
        offset = elOffset - margin;
    }

    var scrollOffset = parent.scrollTop() + offset - parentViewTop;

    parent.animate({scrollTop:scrollOffset}, speed);
    // parent.scrollTop(scrollOffset, speed);
}

그리고 그것들을 사용하십시오 :

scrollToTop($innerListItem, $parentDiv, 200);
// or
scrollToCenter($innerListItem, $parentDiv, 200);


답변

오랫동안 가지고 놀았을 때, 이것이 내가 생각해 낸 것입니다.

    jQuery.fn.scrollTo = function (elem) {
        var b = $(elem);
        this.scrollTop(b.position().top + b.height() - this.height());
    };

나는 이것을 이렇게 부른다

$("#basketListGridHolder").scrollTo('tr[data-uid="' + basketID + '"]');


답변