새로 고침시 자동 브라우저 스크롤 방지


95

페이지 a로 이동하여 스크롤 한 다음 새로 고침하면 페이지를 떠난 지점에서 새로 고침됩니다. 이것은 훌륭하지만 URL에 앵커 위치가있는 페이지에서도 발생합니다. 예를 들어 링크를 클릭하고 http://example.com/post/244#comment5주변을 둘러 본 후 페이지를 새로 고치면 앵커에 있지 않고 페이지가 점프합니다. 자바 스크립트로 이것을 방지하는 방법이 있습니까? 그래서 당신이 항상 앵커로 이동하는 것은 중요하지 않습니다.


jQuery 솔루션이 괜찮습니까 아니면 일반 js를 원하십니까?
— mrtsherman

답변:


16

이 솔루션은 브라우저 동작의 변경으로 인해 더 이상 권장되지 않습니다. 다른 답변을 참조하십시오.

기본적으로 앵커가 사용되면 창 스크롤 이벤트에 바인딩합니다. 첫 번째 스크롤 이벤트는 브라우저가 수행하는 자동 위치 조정에 속해야한다는 생각입니다. 이것이 발생하면 우리는 우리 자신의 위치를 ​​변경하고 바운드 이벤트를 제거합니다. 이는 후속 페이지 스크롤이 시스템을 지루하게하는 것을 방지합니다.

$(document).ready(function() {
    if (window.location.hash) { 
        //bind to scroll function
        $(document).scroll( function() {
            var hash = window.location.hash
            var hashName = hash.substring(1, hash.length);
            var element;

            //if element has this id then scroll to it
            if ($(hash).length != 0) {
                element = $(hash);
            }
            //catch cases of links that use anchor name
            else if ($('a[name="' + hashName + '"]').length != 0)
            {
                //just use the first one in case there are multiples
                element = $('a[name="' + hashName + '"]:first');
            }

            //if we have a target then go to it
            if (element != undefined) {
                window.scrollTo(0, element.position().top);
            }
            //unbind the scroll event
            $(document).unbind("scroll");
        });
    }

});

내가 생각해야 할 사용 사례 중 하나는 자동 스크롤이 발생하기 전에 사용자가 페이지를 스크롤하는 경우입니다. 자동 스크롤링은 페이지가 완전히로드 된 후에 만 ​​발생합니다. 사용자가 이전에 스크롤하면 자동 스크롤이 취소됩니다. 따라서 사용자 시작 스크롤과 브라우저 시작을 구별하는 방법이 필요합니다. 나는 이것을하는 방법을 모르지만, 내가 기억하는대로 그것은 가능하다.
— mrtsherman

1
부야! 이것은 재미있는 심야 문제였습니다. 그래도 내 책상에서 잠들 때 당신 잘못이라고 상사에게 말하고 있어요. 방금 return 문을 제거하기 위해 빠르게 변경했습니다. 이것은 스크롤 이벤트에 대해 추가 한 바인딩 해제를 방해했습니다.
— mrtsherman

처음에는 작은 기본 예제 파일에서이 작업을 확인하여 확인했습니다. 제대로 작동하는지 확인한 후에는 내 프로젝트에서 작동하지 않는 방식에 당황했습니다. 제거 프로세스를 통해 CSS 파일에서 오류를 일으키는 단일 스타일 선언을 찾았습니다. 그것은 외부 글꼴의 적용이었습니다. 코드를 함수로 래핑하고 이제 doc.ready 핸들러 내에서 $ (window) .load () 핸들러로 전달합니다. 이제 작동하도록 이음새가 생깁니다 (약간의 초기 페이지 깜박임). 코드 감사합니다! 이것이 확실한 해결책인지 알려주세요.
— ThomasReggi

1
페이지가로드 된 후로드되는 콘텐츠가있는 경우 작동하지 않습니다. 예 : 배너로 ajax에서 채워질 2div가 있습니다.
— Decebal

@FlashThunder- "작동하지 않음"을 정의 할 수 있습니까? 콘솔 메시지를 게시 하시겠습니까?
— mrtsherman

151

Chrome에서는 scrollTop을 0으로 강제 설정하더라도 첫 번째 스크롤 이벤트 이후에 점프합니다.

다음과 같이 스크롤을 바인딩해야합니다.

$(window).on('beforeunload', function() {
    $(window).scrollTop(0);
});

따라서 브라우저는 새로 고침 전 처음에 있다고 믿도록 속입니다.


5
스크롤링을 엉망으로 만들고 싶지 않은 경우 허용되는 답변보다 훨씬 유용합니다.
— Dan Abramov 2013 년

2
이것은 Chrome 33에서 작업을 수행하지 않습니다. 새 페이지를로드하기 전에 맨 위로 스크롤된다는 의미입니다. 그러나 브라우저는 여전히 이전 스크롤 위치를 기억하고 해당 위치로 동일한 자동 스크롤을 수행합니다.
— Haralan Dobrev

1
Chrome 36, Firefox 30 및 IE 11에서 테스트되었습니다. 잘 작동합니다!
— Fizzix

24
비 jQuery 구현의 경우 : window.onbeforeunload = function(){ window.scrollTo(0,0); }
— ProfNandaa 2014

5
'언로드'대신 '베포 른로드'이벤트를 선택한 이유는 무엇입니까? 내 테스트에 따르면 마지막 페이지는 브라우저에서 페이지를 실제로 언로드하기 전에 맨 위로 이동하는 것을 방지 할 수 있습니다.
— Aleksandr Zonov

74

자동 스크롤 복원을 비활성화하려면이 태그를 헤드 섹션에 추가하면됩니다.

<script>history.scrollRestoration = "manual"</script>

IE에서는 지원하지 않습니다. 브라우저 호환성.


3
IE / Edge에서 사용할 수 있다면 이것이 가장 좋은 대답입니다. 여기에서 구현하도록 투표 할 수 있습니다. wpdev.uservoice.com/forums/257854-microsoft-edge-developer/…
— The Chewy

4
이것은 2019 년의 정답이 될 것입니다. 다른 어떤 방법도 100 % 작동하지 않습니다.
— Limbo

2
이것이 최선의 해결 책임을 확인할 수 있습니다. 여기에있는 다른 솔루션은 Mobile Safari에서 작동하지 않으며 버벅 거릴 수 있습니다. 이것은 완벽하게 작동합니다.
— user3330820

20

몇 번의 실패 후에 마침내 나는 트릭을 할 수있었습니다. anzo 는 beforeunload사용자가 페이지를 다시로드하거나 링크를 클릭 할 때 페이지가 맨 위로 이동하도록하므로 여기에서 정확 합니다. 그렇게하는 unload것이 분명한 방법입니다.

$(window).on('unload', function() {
   $(window).scrollTop(0);
});

자바 스크립트 방식 ( ProfNandaa 에게 감사 드립니다 ) :

window.onunload = function(){ window.scrollTo(0,0); }

수정 : 2015 년 7 월 16 일

unload이벤트 에도 불구하고 Firefox에는 점프 문제가 여전히 있습니다 .


3
이 솔루션은 beforeunload새로 고침 및 앵커 클릭시 페이지 상단으로 이동하는 것을 방지하기 때문에 솔루션 보다 훨씬 낫습니다 .
— BradGreens

@BradGreens 최신 Chrome에서는 사용자가 다른 탭으로 전환 할 때도 onunload 이벤트가 트리거되며 이는 예상치 못한 일입니다. onbeforeunload는 여전히 유효한 해결 방법입니다.
— Telvin Nguyen

@TelvinNguyen 이것에 대한 자원을 줄 수 있습니까? 나는 이것을 Google 크롬 72에서 테스트했으며 여전히 잘 작동합니다.
— Janaka Dombawela

@JanakaDombawela 내가 말한 것 : 문제를 일으키는 새 탭 이동이 잘못되었습니다. 그러나이 예제에서 이벤트 onunload가 jQuery 1.9.1과 jQuery 1.8.3을 사용해도 제대로 트리거되지 않음을 알 수 있습니다. onunload는 신뢰할 수 없습니다. jsfiddle.net/6s4jhdug/3(1.8.3 ) jsfiddle.net/frt45ue9(1.9.1 )
— Telvin Nguyen

3

다음은보다 일반적인 접근 방식입니다. 브라우저가 스크롤 (또는 보이는 것처럼 맨 위로 점프)하는 것을 방지하는 대신 페이지의 이전 위치를 복원합니다. 즉, localStorage에 페이지의 현재 y 오프셋을 기록하고 페이지가로드되면이 위치로 스크롤합니다.

function storePagePosition() {
  var page_y = window.pageYOffset;
  localStorage.setItem("page_y", page_y);
}


window.addEventListener("scroll", storePagePosition);


var currentPageY;

try {
  currentPageY = localStorage.getItem("page_y");

  if (currentPageY === undefined) {
    localStorage.setItem("page_y") = 0;
  }

  window.scrollTo( 0, currentPageY );
} catch (e) {
    // no localStorage available
}

2

페이지가 맨 위에로드되도록 끝에 #을 입력 할 수 있습니다.

매우 간단하기 때문에 모든 브라우저, 모바일 및 데스크톱에서 작동합니다.

$(document).ready(function() {
var url = window.location.href;
console.log(url);
if( url.indexOf('#') < 0 ) {
    window.location.replace(url + "#");
} else {
    window.location.replace(url);
}

});

// 마지막에 #이있는 페이지를로드합니다.


내 서버에서 직접 시도하면 마술처럼 작동합니다. 그러나 내 cms가 마크 업 오류를 제공합니다. 그게 뭔지 모르겠어요.
— alice

1
당신은 워드 프레스의 변화를 사용하는 경우 $ jQuery를위한
— Herzling

1

이것은 나를 위해 작동합니다.

    //Reset scroll top

    history.scrollRestoration = "manual"

    $(window).on('beforeunload', function(){
          $(window).scrollTop(0);
    });

-2

할 수 있어야합니다.

Onload, window.location.hash값이 있는지 확인하십시오 . 그렇다면 해시 값과 일치하는 ID를 가진 요소를 가져옵니다. 요소의 위치 (offsetTop / offsetLeft에 대한 재귀 호출)를 찾은 다음 해당 값을 window.scrollTo(x, y)메서드에 전달합니다 .

페이지를 원하는 요소로 스크롤해야합니다.


3
이것은 브라우저가 자동 스크롤을 수행하는 것을 막지는 않습니다. 이것이 바로이 질문에 관한 것입니다.
— Haralan Dobrev
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.