programing

오버플로된 Div 내의 요소로 스크롤하려면 어떻게 해야 합니까?

newstyles 2023. 10. 6. 20:57

오버플로된 Div 내의 요소로 스크롤하려면 어떻게 해야 합니까?

한 번에 5개만 보여줄 수 있는 디브 안에 리스트 아이템이 20개 있습니다.10번 항목으로 스크롤한 다음 20번 항목으로 스크롤하는 좋은 방법은 무엇입니까?저는 모든 물건의 높이를 알고 있습니다.

스크롤투 플러그인은 이렇게 하지만, 소스를 제대로 이해하지 않고는 이해하기가 쉽지 않습니다.저는 이 플러그인을 사용하고 싶지 않습니다.

제가 2가지 요소를 가지는 기능이 있다고 가정해 보겠습니다.$parentDiv,$innerListItem,둘 다 아니다.$innerListItem.offset().top도 아니다$innerListItem.positon().top$parentDiv에 대한 올바른 스크롤Top을 제공합니다.

$innerListItem.position().top사실은 상대적인 것입니다..scrollTop()그 최초의 조상의 것입니다.그래서 정확한 것을 계산하는 방법은$parentDiv.scrollTop()가치는 다음을 확인하는 것으로 시작합니다.$parentDiv위치합니다.아직 명시적인 내용이 없는 경우position,사용하다position: relative. 요소들은$innerListItem그리고 그 조상들은 지금까지$parentDiv명시적인 입장을 가질 필요가 없습니다.이제 로 스크롤할 수 있습니다.$innerListItem다음 항목 포함:

// 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 object] 등.

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)에서 테스트되었습니다.

전체 페이지를 스크롤하려면 이 질문을 확인합니다.

오버플로우 디브가 페이지 상단에 없을 수도 있기 때문에 글렌 모스의 답변을 조정했습니다.

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

저는 이것을 응답 템플릿이 있는 구글 지도 애플리케이션에서 사용하고 있었습니다.해상도 > 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;
};

허용된 답변은 스크롤 가능한 요소의 직접적인 자식과만 작동하고, 다른 답변은 스크롤 가능한 요소의 자식 중심에 맞추지 않습니다.

HTML 예시:

<div class="scrollable-box">
    <div class="row">
        <div class="scrollable-item">
            Child 1
        </div>
        <div class="scrollable-item">
            Child 2
        </div>
        <div class="scrollable-item">
            Child 3
        </div>
        <div class="scrollable-item">
            Child 4
        </div>
        <div class="scrollable-item">
            Child 5
        </div>
        <div class="scrollable-item">
            Child 6
        </div>
        <div class="scrollable-item">
            Child 7
        </div>
        <div class="scrollable-item">
            Child 8
        </div>
        <div class="scrollable-item">
            Child 9
        </div>
        <div class="scrollable-item">
            Child 10
        </div>
        <div class="scrollable-item">
            Child 11
        </div>
        <div class="scrollable-item">
            Child 12
        </div>
        <div class="scrollable-item">
            Child 13
        </div>
        <div class="scrollable-item">
            Child 14
        </div>
        <div class="scrollable-item">
            Child 15
        </div>
        <div class="scrollable-item">
            Child 16
        </div>
    </div>
</div>

<style>
.scrollable-box {
    width: 800px;
    height: 150px;
    overflow-x: hidden;
    overflow-y: scroll;
    border: 1px solid #444;
}
.scrollable-item {
    font-size: 20px;
    padding: 10px;
    text-align: center;
}
</style>

작은 jQuery 플러그인을 빌드합니다.

$.fn.scrollDivToElement = function(childSel) {
    if (! this.length) return this;

    return this.each(function() {
        let parentEl = $(this);
        let childEl = parentEl.find(childSel);

        if (childEl.length > 0) {
            parentEl.scrollTop(
                parentEl.scrollTop() - parentEl.offset().top + childEl.offset().top - (parentEl.outerHeight() / 2) + (childEl.outerHeight() / 2)
            );
        }
    });
};

용도:

$('.scrollable-box').scrollDivToElement('.scrollable-item:eq(12)');

설명:

  1. parentEl.scrollTop(...)스크롤 막대의 현재 수직 위치를 설정합니다.

  2. parentEl.scrollTop()스크롤 막대의 현재 수직 위치를 가져옵니다.

  3. parentEl.offset().top문서에 대한 상위 El의 현재 좌표를 가져옵니다.

  4. childEl.offset().top문서를 기준으로 하위 El의 현재 좌표를 가져옵니다.

  5. parentEl.outerHeight() / 2하위 요소의 바깥쪽 높이를 절반으로 나눕니다(중심을 맞추기를 원하므로).

  6. 사용 시:

$(parent).scrollDivToElement(child);

부모는 스크롤 가능한 div이고 DOM 요소의 문자열 또는 jQuery 개체일 수 있습니다.
하위 항목은 스크롤할 하위 항목이며 DOM 요소의 문자열 또는 jQuery 개체일 수 있습니다.

코데펜 데모

저는 제 삶을 좀더 편안하게 하기 위해 다음 두 가지 기능을 씁니다.

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 + '"]');

언급URL : https://stackoverflow.com/questions/2346011/how-do-i-scroll-to-an-element-within-an-overflowed-div