jQuery로 scrollTop에 애니메이션을 적용 할 수 있습니까?


226

부드럽게 아래로 스크롤하고 싶습니다. 특히 jQuery에 이미 함수가있는 경우 그 함수를 작성하고 싶지 않습니다.

답변:


463

당신은 사용할 수 있습니다 이 같은 속성을 :.animate()scrollTop

$("html, body").animate({ scrollTop: "300px" });

아주 좋은 .. 이것을 위해 플러그인을 사용할 필요가 없습니다.
Amol M Kulkarni

15
왜 필요 둘 않습니다 htmlbody? 여기에 약간의 통찰력이 있습니다 : stackoverflow.com/questions/2123690/… . 그러나 완전한 대답은 아닙니다.
Haralan Dobrev

28
body는 웹킷에서, HTML은 firefox에서 사용합니다.
Jory

2
참고 : 경우 <html>overflow-x:hidden;이 애니메이션이 작동하지 않습니다. ( overflow-y:hiddenoverflow:hidden에는 효과가 없지만 테스트하지는 않았습니다.
collinhaines

1
body올해 초 Chrome에서 일한 것으로 생각 되지만 이제는이어야 html합니다.
Nick Davies

73

Nick의 대답은 훌륭합니다. animate () 호출 내에서 complete () 함수를 지정할 때는 두 개의 선택기 (html 및 body)가 선언되어 두 번 실행되므로주의해야합니다.

$("html, body").animate(
    { scrollTop: "300px" },
    {
        complete : function(){
            alert('this alert will popup twice');
        }
    }
);

이중 콜백을 피하는 방법은 다음과 같습니다.

var completeCalled = false;
$("html, body").animate(
    { scrollTop: "300px" },
    {
        complete : function(){
            if(!completeCalled){
                completeCalled = true;
                alert('this alert will popup once');
            }
        }
    }
);

1
문제는 왜 'body'가 아닌 'html, body'에 애니메이션을 적용하겠습니까?
Lior

21
사용중인 브라우저에 따라 body 또는 html에 애니메이션을 적용 할 수 있습니다. BOTH에 애니메이션을 적용하면 더 많은 브라우저를 사용할 수 있습니다.
Bene

그러나이 경우 반복적으로 호출 해야하는 경우 (버튼 클릭 이벤트) 또는 내가 놓친 것이 있습니까?
HoGo

예,이 경우에는 한 번만 팝업됩니다. 반복적으로 애니메이션을 적용해야하는 경우에는 completeCalled 변수를 애니메이션 기능을 실행하는 콜백 함수에 대해 로컬로 만듭니다. 이렇게하면 클릭하면 여전히 한 번만 팝업되지만 다시 클릭하면 다시 한 번 팝업됩니다.
Kita

이중 콜백 함수 발생을 방지하기 위해 함수 호출 die()전에 live()함수를 사용할 수 있습니다 . 이 보증은 live()처리기가 한 번만 호출됩니다.
Lord Nighton

27

Nick의 답변은 훌륭하게 작동하고 기본 설정은 훌륭하지만 모든 옵션 설정을 완료하여 스크롤을보다 완벽하게 제어 할 수 있습니다.

다음은 API에서 보이는 모습입니다.

.animate( properties [, duration] [, easing] [, complete] )

그래서 당신은 이런 식으로 할 수 있습니다 :

.animate( 
    {scrollTop:'300px'},
    300,
    swing,
    function(){ 
       alert(animation complete! - your custom code here!); 
       } 
    )

다음은 jQuery .animate 함수 API 페이지입니다. http://api.jquery.com/animate/


15

Kita가 언급 한 것처럼 'html'과 'body'모두에서 애니메이션을 적용하면 여러 콜백이 발생하는 문제가 있습니다. 둘 다 애니메이션을 만들고 후속 콜백을 차단하는 대신 기본 기능 감지를 사용하고 단일 객체의 scrollTop 속성에만 애니메이션을 적용하는 것을 선호합니다.

이 다른 스레드에서 허용되는 대답은 애니메이션을 적용하려는 객체의 scrollTop 속성에 대한 통찰력을 제공합니다 .IE8의 pageYOffset 스크롤 및 애니메이션

// UPDATE: don't use this... see below
// only use 'body' for IE8 and below
var scrollTopElement = (window.pageYOffset != null) ? 'html' : 'body';

// only animate on one element so our callback only fires once!
$(scrollTopElement).animate({ 
        scrollTop: '400px' // vertical position on the page
    },
    500, // the duration of the animation 
    function() {       
        // callback goes here...
    })
});

업데이트---

위의 기능 감지 시도가 실패합니다. 웹킷 유형 브라우저 pageYOffset 특성은 doctype이있을 때 항상 0을 리턴하므로 한 행으로 수행하는 방법이없는 것 같습니다. 대신 애니메이션이 실행될 때마다 단일 콜백을 약속하는 방법을 찾았습니다.

$('html, body')
    .animate({ scrollTop: 100 })
    .promise()
    .then(function(){
        // callback code here
    })
});

1
여기서 promise ()를 사용하면 천재입니다.
Allan Bazinet

더 많은 투표가 필요합니다. 나는 전에 이것을 위해 사용 된 약속을 본 적이 없으며, 이것은 내가 몇 개월마다 검색하는 결과이다. Allan이 말했듯이 천재.
Tortilaman

14

나는 $('html, body')해킹 보다 더 나은 해결책이라고 생각합니다 .

그것은 한 줄짜리가 아니지만 내가 가진 문제 는 애니메이션 중에 $('html, body')기록 $(window).scrollTop()하면 때로는 수백 픽셀 씩 값이 점프한다는 것을 알 수 있습니다 (물론 그런 것은 보이지 않습니다) 시각적으로 발생). 자동 스크롤 중에 사용자가 스크롤 막대를 잡거나 마우스 휠을 돌리면 애니메이션을 취소 할 수 있도록 값을 예측할 수 있어야했습니다.

다음은 스크롤을 부드럽게 움직이는 함수입니다.

function animateScrollTop(target, duration) {
    duration = duration || 16;
    var scrollTopProxy = { value: $(window).scrollTop() };
    if (scrollTopProxy.value != target) {
        $(scrollTopProxy).animate(
            { value: target }, 
            { duration: duration, step: function (stepValue) {
                var rounded = Math.round(stepValue);
                $(window).scrollTop(rounded);
            }
        });
    }
}

아래는 사용자 상호 작용에 대한 애니메이션을 취소하고 대상 값에 도달 할 때까지 다시 실행하는보다 복잡한 버전입니다. 이는 scrollTop을 즉시 설정하려고 할 때 유용합니다 (예 : 단순히 호출 $(window).scrollTop(1000)-내 경험에서 작동하지 않습니다) 시간의 50 %.)

function animateScrollTop(target, duration) {
    duration = duration || 16;

    var $window = $(window);
    var scrollTopProxy = { value: $window.scrollTop() };
    var expectedScrollTop = scrollTopProxy.value;

    if (scrollTopProxy.value != target) {
        $(scrollTopProxy).animate(
            { value: target },
            {
                duration: duration,

                step: function (stepValue) {
                    var roundedValue = Math.round(stepValue);
                    if ($window.scrollTop() !== expectedScrollTop) {
                        // The user has tried to scroll the page
                        $(scrollTopProxy).stop();
                    }
                    $window.scrollTop(roundedValue);
                    expectedScrollTop = roundedValue;
                },

                complete: function () {
                    if ($window.scrollTop() != target) {
                        setTimeout(function () {
                            animateScrollTop(target);
                        }, 16);
                    }
                }
            }
        );
    }
}

7

다른 예제에서 페이지를 새로 고친 후 애니메이션이 항상 페이지 상단에서 시작되는 문제가있었습니다.

CSS를 직접 애니메이션하지 않고 window.scrollTo();각 단계를 호출 하여이 문제를 해결했습니다 .

$({myScrollTop:window.pageYOffset}).animate({myScrollTop:300}, {
  duration: 600,
  easing: 'swing',
  step: function(val) {
    window.scrollTo(0, val);
  }
});

이것은 또한 주위에 얻을 htmlbody는 크로스 브라우저 자바 스크립트를 사용하고 같은 문제를 해결합니다.

jQuery의 애니메이션 기능으로 수행 할 수있는 작업에 대한 자세한 내용 은 http://james.padolsey.com/javascript/fun-with-jquerys-animate/ 를 참조하십시오.


5

특정 지속 시간으로 스크롤 페이지에 jQuery 애니메이션을 사용할 수 있습니다.

$("html, body").animate({scrollTop: "1024px"}, 5000);

여기서 1024px는 스크롤 오프셋이고 5000은 애니메이션 지속 시간 (밀리 초)입니다.


좋은 대답입니다! 지속 시간 옵션을 포함하게되어 기쁩니다. 그냥 추가하고 싶었습니다 $("html, body").animate({scrollTop: 1024}, 5000);.
Ryan Taylor

4

scrollTo 플러그인을 사용해보십시오 .


scrollTo는 더 이상 해당 사이트의 프로젝트가 아닌 것 같습니다.
Jim

이를 수행하는 코드는 매우 간단합니다. 한 줄의 코드로 할 수있는 작업을 수행하기 위해 플러그인을 추가하는 이유는 무엇입니까?
Gavin

4
4 년 전 그렇게 간단하지 않았다 .. :
타투 Ulmanen

4
$(".scroll-top").on("click", function(e){
   e.preventDefault();
   $("html, body").animate({scrollTop:"0"},600);
});

1

페이지 끝에서 아래로 이동하려면 (아래로 스크롤하지 않아도 됨) 다음을 사용할 수 있습니다.

$('body').animate({ scrollTop: $(document).height() });

0

그러나 스크롤하는 동안 애니메이션을 실제로 추가하려면 현재 30 개 이상의 여유 스타일을 지원하는 간단한 플러그인 ( AnimateScroll )을 사용해보십시오


-3

크로스 브라우저 코드는 다음과 같습니다.

$(window).scrollTop(300); 

애니메이션은 없지만 어디에서나 작동합니다.


6
"jQuery로 scrollTop에 애니메이션을 적용하는 방법"을 찾고있었습니다. "애니메이션없이"는 답변이 아닙니다.
Bryan Field
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.