jQuery를 사용하여 요소를 스크롤하여 볼 수 있습니까?


169

를 사용하여 격자 형식의 이미지가있는 HTML 문서가 있습니다 <ul><li><img.... 브라우저 창에는 세로 및 가로 스크롤이 있습니다.

질문 : 이미지를 클릭 할 때 <img>방금 클릭 한 이미지가있는 위치로 전체 문서를 스크롤하려면 top:20px; left:20px어떻게해야합니까?

JavaScript를 처음 접했을 때도 비슷한 게시물을 찾아 보았지만 이것이 어떻게 달성되는지 이해하고 싶습니다.


답변:


192

작동 방식을 알고 싶으 니 단계별로 설명하겠습니다.

먼저 이미지의 클릭 핸들러로 함수를 바인딩하려고합니다.

$('#someImage').click(function () {
    // Code to do scrolling happens here
});

그러면 클릭 핸들러가 이미지에 적용됩니다 id="someImage". 당신이이 작업을 수행하려면 모든 이미지 교체 '#someImage'와 함께 'img'.

실제 스크롤 코드는 다음과 같습니다.

  1. 문서와 관련된 이미지 오프셋을 가져옵니다.

    var offset = $(this).offset(); // Contains .top and .left
  2. 20에서 빼기 topleft:

    offset.left -= 20;
    offset.top -= 20;
  3. 지금의 스크롤 상단과 스크롤 왼쪽 CSS 속성 애니메이션 <body><html>:

    $('html, body').animate({
        scrollTop: offset.top,
        scrollLeft: offset.left
    });

3
이것은 간단한 레이아웃에서만 작동합니다. .scrollIntoView요소가 여러 개의 오버플로 된 컨테이너 내에 중첩 된 경우 W3C 메서드가 수행 하는 방식을 모두 처리하지는 않습니다 .
natevw

2
왜 바퀴를 재발견해야합니까? Element.scrollIntoView(): developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
Serge

@Serge는 모든 브라우저에서 구현되지 않은 작업 초안이므로
John Smith

@JohnSmith주의해서 게시 한 링크 인 "브라우저 호환성"섹션을 읽으십시오.scrollIntoView
Serge

@ Serge 죄송합니다, 나는 몰랐습니다. scrollIntoViewOption (넓게 지원되지 않는 것)도 있습니다. 충분하다고 생각합니다.
John Smith

377

scrollIntoView모든 주요 브라우저에서 지원 하는 DOM 메소드가 있는데 ,이 메소드 는 뷰포트의 상단 / 왼쪽에 (또는 가능한 한) 요소를 정렬합니다.

$("#myImage")[0].scrollIntoView();

지원되는 브라우저에서 다음 옵션을 제공 할 수 있습니다.

$("#myImage")[0].scrollIntoView({
    behavior: "smooth", // or "auto" or "instant"
    block: "start" // or "end"
});

또는 모든 요소에 고유 한 ID hash가있는 location경우 뒤로 / 앞으로 단추 지원을 위해 객체 의 속성을 변경할 수 있습니다 .

$(document).delegate("img", function (e) {
    if (e.target.id)
        window.location.hash = e.target.id;
});

그 후 scrollTop/ scrollLeft속성을 -20으로 조정하십시오 .

document.body.scrollLeft -= 20;
document.body.scrollTop -= 20;

2
감사합니다! 다른 5 개의 기사와 당신은 그것을 완벽하게 못 박았습니다. 내 유스 케이스는 부트 스트랩 대화 상자의 컨테이너로 스크롤해야 볼 수 있습니다.
Stephen Patten

10
참고로 : $("#myImage")[0].scrollIntoView(false);창 아래쪽에 요소를 정렬합니다.
Philipp

1
"부드러운"동작은 널리 지원되지 않으며, scrollIntoView일종의 애니메이션이없는 사용자에게는 혼란스러운 경험이 될 수 있습니다.
Cody Duval 2016 년

1
@ JohnHenckel : 그것은 잘못된 것입니다 .IE 5.5조차도 scrollIntoView부울 매개 변수가 있습니다. 나중에 caniuse.com에 대한 풀 요청을 보내려고합니다.
Andy E

1
참고 : Chrome을 사용하면 <td>요소를보기로 스크롤 할 수 없었고 대신 부모 ( <tr>) 를 스크롤 해야 작동했습니다.
CrazyTim

13

내가 본 가장 간단한 솔루션

var offset = $("#target-element").offset();
$('html, body').animate({
    scrollTop: offset.top,
    scrollLeft: offset.left
}, 1000);

여기 튜토리얼


덜 간단하게 만들 위험이 있기 때문에 수평 스크롤도 지원하도록 이것을 편집했습니다.
jpaugh

7

요소를 뷰로 직접 스크롤하는 방법이 있지만 요소와 상대적인 점으로 스크롤하려면 수동으로 수행해야합니다.

클릭 핸들러 내에서 문서를 기준으로 요소의 위치를 ​​가져 와서 빼고 20사용하십시오 window.scrollTo.

var pos = $(this).offset();
var top = pos.top - 20;
var left = pos.left - 20;
window.scrollTo((left < 0 ? 0 : left), (top < 0 ? 0 : top));

7

jQuery.scrollTo 플러그인을 살펴보십시오 . 여기 데모가 있습니다 있습니다.

이 플러그인에는 기본 scrollIntoView가 제공 하는 것 이상의 다양한 옵션이 있습니다. 예를 들어, 스크롤을 부드럽게 설정 한 다음 스크롤이 완료 될 때의 콜백을 설정할 수 있습니다.

"scroll"태그가 지정된 모든 JQuery 플러그인을 살펴볼 수도 있습니다 .


필자의 경우 모든 브라우저에서 서로 다른 오프셋 / 위치를 얻었고이 플러그인으로 문제를 해결했습니다. 감사!
LaurelB

4

내장 된 브라우저 기능을 멋지게 매핑하는 빠른 jQuery 플러그인은 다음과 같습니다.

$.fn.ensureVisible = function () { $(this).each(function () { $(this)[0].scrollIntoView(); }); };

...

$('.my-elements').ensureVisible();

3

시행 착오 후에이 기능을 생각해 내고 iframe에서도 작동합니다.

function bringElIntoView(el) {    
    var elOffset = el.offset();
    var $window = $(window);
    var windowScrollBottom = $window.scrollTop() + $window.height();
    var scrollToPos = -1;
    if (elOffset.top < $window.scrollTop()) // element is hidden in the top
        scrollToPos = elOffset.top;
    else if (elOffset.top + el.height() > windowScrollBottom) // element is hidden in the bottom
        scrollToPos = $window.scrollTop() + (elOffset.top + el.height() - windowScrollBottom);
    if (scrollToPos !== -1)
        $('html, body').animate({ scrollTop: scrollToPos });
}

2

그냥 팁. 파이어 폭스에서만 작동

Element.scrollIntoView ();


4
이것은 부울 매개 변수가 있거나 전혀 매개 변수가없는 모든 브라우저에서 작동합니다. 고급 객체 매개 변수 만 지원됩니다.
Risord

developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView 에 따르면 이에 대한 브라우저 지원이 부족합니다.
lfender6445

: 지금 충분히 잘 유일한 오페라 미니, 지원되는 caniuse.com/#search=scrollIntoView
존 목련

거기에는 매우 가벼운 폴리 필이 많이 있습니다.
Martin James

1

내 UI에는 썸바 내에 세로로 스크롤되는 썸네일 목록이 있습니다. 목표는 썸바의 중앙에서 현재 썸을 바로 만드는 것입니다. 나는 승인 된 대답에서 시작했지만 현재 엄지 손가락을 실제로 가운데에 맞추는 데 약간의 조정이 있음을 발견했습니다. 이것이 다른 누군가를 돕기를 바랍니다.

마크 업 :

<ul id='thumbbar'>
    <li id='thumbbar-123'></li>
    <li id='thumbbar-124'></li>
    <li id='thumbbar-125'></li>
</ul>

jquery :

// scroll the current thumb bar thumb into view
heightbar   = $('#thumbbar').height();
heightthumb = $('#thumbbar-' + pageid).height();
offsetbar   = $('#thumbbar').scrollTop();


$('#thumbbar').animate({
    scrollTop: offsetthumb.top - heightbar / 2 - offsetbar - 20
});

0

아래로 스크롤하여 끝 또는 아래쪽으로 이동하는 간단한 2 단계.

1 단계 : 스크롤 가능 (대화) div의 전체 높이를 가져옵니다.

2 단계 : 1 단계에서 얻은 값을 사용하여 해당 스크롤 가능 (대화) div에 scrollTop을 적용합니다.

var fullHeight = $('#conversation')[0].scrollHeight;

$('#conversation').scrollTop(fullHeight);

대화 div의 모든 추가에 대해 위의 단계를 적용해야합니다.


0

모든 상황을 처리하는 솔루션을 찾으려고 시도한 후 (스크롤 애니메이션 옵션, 스크롤하여 객체 주위에 패딩, iframe과 같은 모호한 환경에서도 작동) 마침내 자체 솔루션을 작성했습니다. 다른 많은 솔루션이 실패했을 때 작동하는 것처럼 보이므로 공유하겠다고 생각했습니다.

function scrollIntoViewIfNeeded($target, options) {

    var options = options ? options : {},
    $win = $($target[0].ownerDocument.defaultView), //get the window object of the $target, don't use "window" because the element could possibly be in a different iframe than the one calling the function
    $container = options.$container ? options.$container : $win,        
    padding = options.padding ? options.padding : 20,
    elemTop = $target.offset().top,
    elemHeight = $target.outerHeight(),
    containerTop = $container.scrollTop(),
    //Everything past this point is used only to get the container's visible height, which is needed to do this accurately
    containerHeight = $container.outerHeight(),
    winTop = $win.scrollTop(),
    winBot = winTop + $win.height(),
    containerVisibleTop = containerTop < winTop ? winTop : containerTop,
    containerVisibleBottom = containerTop + containerHeight > winBot ? winBot : containerTop + containerHeight,
    containerVisibleHeight = containerVisibleBottom - containerVisibleTop;

    if (elemTop < containerTop) {
        //scroll up
        if (options.instant) {
            $container.scrollTop(elemTop - padding);
        } else {
            $container.animate({scrollTop: elemTop - padding}, options.animationOptions);
        }
    } else if (elemTop + elemHeight > containerTop + containerVisibleHeight) {
        //scroll down
        if (options.instant) {
            $container.scrollTop(elemTop + elemHeight - containerVisibleHeight + padding);
        } else {
            $container.animate({scrollTop: elemTop + elemHeight - containerVisibleHeight + padding}, options.animationOptions);
        }
    }
}

$target 필요한 경우보기로 스크롤하려는 객체가 포함 된 jQuery 객체입니다.

options (선택 사항) 객체에 전달 된 다음 옵션을 포함 할 수 있습니다.

options.$container-$ target의 포함 요소 (즉, 스크롤 막대가있는 dom의 요소)를 가리키는 jQuery 객체. $ target 요소가 포함 된 윈도우로 기본 설정되며 iframe 윈도우를 선택하기에 충분합니다. 속성 이름에 $를 포함시켜야합니다.

options.padding-스크롤 할 때 객체의 위 또는 아래에 추가 할 패딩 (픽셀)입니다. 이런 식으로 창 가장자리에 맞지 않습니다. 기본값은 20입니다.

options.instant-true로 설정하면 jQuery 애니메이션이 사용되지 않고 스크롤이 즉시 올바른 위치에 팝업됩니다. 기본값은 false입니다.

options.animationOptions-jQuery 애니메이션 함수에 전달하려는 모든 jQuery 옵션 ( http://api.jquery.com/animate/ 참조 ) 이를 통해 애니메이션 지속 시간을 변경하거나 스크롤이 완료되면 콜백 함수를 실행할 수 있습니다. options.instantfalse로 설정된 경우에만 작동합니다 . 인스턴트 애니메이션이 필요하지만 콜백이 필요한 경우을 options.animationOptions.duration = 0사용하는 대신 설정하십시오 options.instant = true.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.