복붙노트

[JQUERY] 페이지 스크롤없이에 location.hash 수정

JQUERY

페이지 스크롤없이에 location.hash 수정

해결법


  1. 1.1 단계 : 당신은 해시가 설정 될 때까지, 노드 ID를 완화 할 필요가있다. 이것은 백에 첨가 한 다음 해시 세트되는 동안 오프 노드 ID를 제거에 의해 수행된다.

    1 단계 : 당신은 해시가 설정 될 때까지, 노드 ID를 완화 할 필요가있다. 이것은 백에 첨가 한 다음 해시 세트되는 동안 오프 노드 ID를 제거에 의해 수행된다.

    hash = hash.replace( /^#/, '' );
    var node = $( '#' + hash );
    if ( node.length ) {
      node.attr( 'id', '' );
    }
    document.location.hash = hash;
    if ( node.length ) {
      node.attr( 'id', hash );
    }
    

    2 단계 : 일부 브라우저는 당신이 그 (것)들에게 약간의 도움이 필요하므로 신원 노드가 마지막으로 나타났다 위치에 따라 스크롤을 트리거합니다. 당신은 뷰포트의 상단에 별도의 사업부를 추가 할 필요가, 해시, 다음 롤 모든 것을 다시 그것의 ID를 설정합니다 :

    hash = hash.replace( /^#/, '' );
    var fx, node = $( '#' + hash );
    if ( node.length ) {
      node.attr( 'id', '' );
      fx = $( '<div></div>' )
              .css({
                  position:'absolute',
                  visibility:'hidden',
                  top: $(document).scrollTop() + 'px'
              })
              .attr( 'id', hash )
              .appendTo( document.body );
    }
    document.location.hash = hash;
    if ( node.length ) {
      fx.remove();
      node.attr( 'id', hash );
    }
    

    3 단계 :에 location.hash에 기록하는 대신 플러그인 사용에 랩이 ...


  2. 2.사용 history.replaceState 또는 history.pushState * 해시를 변경합니다. 이는 관련 요소에 점프를 트리거하지 않습니다.

    사용 history.replaceState 또는 history.pushState * 해시를 변경합니다. 이는 관련 요소에 점프를 트리거하지 않습니다.

    $(document).on('click', 'a[href^=#]', function(event) {
      event.preventDefault();
      history.pushState({}, '', this.href);
    });
    

    JSFiddle에 데모

    * 당신은 역사 앞뒤로 지원을 원하는 경우

    당신은 history.pushState를 사용하고 사용자가 실험 scrollRestoration 설정 (크롬 46+ 전용) 체크 아웃 브라우저 (전방 / 후방)의 역사를 버튼을 사용하면 페이지를 스크롤하지 않으려면.

    history.scrollRestoration = 'manual';
    

  3. 3.내가 아주 간단한 해결책을 발견 할 수 있습니다 생각합니다. 문제는 URL의 해시 당신이 스크롤 얻을 페이지 요소는 것입니다. 난 그냥 해시에 텍스트, 이제 더 이상 참조 기존 요소를 앞에 추가하면!

    내가 아주 간단한 해결책을 발견 할 수 있습니다 생각합니다. 문제는 URL의 해시 당신이 스크롤 얻을 페이지 요소는 것입니다. 난 그냥 해시에 텍스트, 이제 더 이상 참조 기존 요소를 앞에 추가하면!

    $(function(){
        //This emulates a click on the correct button on page load
        if(document.location.hash){
         $("#buttons li a").removeClass('selected');
         s=$(document.location.hash.replace("btn_","")).addClass('selected').attr("href").replace("javascript:","");
         eval(s);
        }
    
        //Click a button to change the hash
        $("#buttons li a").click(function(){
                $("#buttons li a").removeClass('selected');
                $(this).addClass('selected');
                document.location.hash="btn_"+$(this).attr("id")
                //return false;
        });
    });
    

    이제 URL은 page.aspx # btn_elementID 페이지의 실제 ID하지 않은으로 나타납니다. 난 그냥 "btn_"제거하고 실제 요소 ID를 얻을 수


  4. 4.원래 코드의 조각 :

    원래 코드의 조각 :

    $("#buttons li a").click(function(){
        $("#buttons li a").removeClass('selected');
        $(this).addClass('selected');
        document.location.hash=$(this).attr("id")
    });
    

    이 같이 변경 :

    $("#buttons li a").click(function(e){
        // need to pass in "e", which is the actual click event
        e.preventDefault();
        // the preventDefault() function ... prevents the default action.
        $("#buttons li a").removeClass('selected');
        $(this).addClass('selected');
        document.location.hash=$(this).attr("id")
    });
    

  5. 5.나는 최근 상태를 유지하면 window.location.hash에 의존하고 window.onhashchange 이벤트가 발사 될 때 어색 바보와 크롬과 웹킷 브라우저는 (심지어 비 표시 대상에) 스크롤 강제하는 발견을 회전 목마를 구축했다.

    나는 최근 상태를 유지하면 window.location.hash에 의존하고 window.onhashchange 이벤트가 발사 될 때 어색 바보와 크롬과 웹킷 브라우저는 (심지어 비 표시 대상에) 스크롤 강제하는 발견을 회전 목마를 구축했다.

    심지어 전파를 중지 핸들러를 등록하려고 :

    $(window).on("hashchange", function(e) { 
      e.stopPropogation(); 
      e.preventDefault(); 
    });
    

    기본 브라우저 동작을 중지 아무것도하지 않았다. I 발견 해결책은 원치 않는 부작용을 유발하지 않고 해쉬 변경 window.history.pushState를 사용 하였다.

     $("#buttons li a").click(function(){
        var $self, id, oldUrl;
    
        $self = $(this);
        id = $self.attr('id');
    
        $self.siblings().removeClass('selected'); // Don't re-query the DOM!
        $self.addClass('selected');
    
        if (window.history.pushState) {
          oldUrl = window.location.toString(); 
          // Update the address bar 
          window.history.pushState({}, '', '#' + id);
          // Trigger a custom event which mimics hashchange
          $(window).trigger('my.hashchange', [window.location.toString(), oldUrl]);
        } else {
          // Fallback for the poors browsers which do not have pushState
          window.location.hash = id;
        }
    
        // prevents the default action of clicking on a link.
        return false;
    });
    

    그런 다음 정상 hashchange 이벤트 및 my.hashchange 모두 수신 할 수 있습니다 :

    $(window).on('hashchange my.hashchange', function(e, newUrl, oldUrl){
      // @todo - do something awesome!
    });
    

  6. 6.자, 이것은 오히려 오래된 주제하지만 난이 '올바른'대답은 CSS와 함께 잘 작동하지 않습니다로 칩을 거라고 생각했다.

    자, 이것은 오히려 오래된 주제하지만 난이 '올바른'대답은 CSS와 함께 잘 작동하지 않습니다로 칩을 거라고 생각했다.

    이 솔루션은 기본적으로 우리가 처음 스크롤 위치를 얻을 수 있도록 페이지를 이동하는 클릭 이벤트를 방지 할 수 있습니다. 그런 다음 우리는 수동으로 해시를 추가하고 브라우저가 자동으로 hashchange 이벤트를 트리거합니다. 우리는 hashchange 이벤트를 캡처하고 올바른 위치로 다시 스크롤합니다. 콜백 분리하고 방지는 코드는 한 곳에서 해킹 당신의 해시를 유지하여 지연의 원인.

    var hashThis = function( $elem, callback ){
        var scrollLocation;
        $( $elem ).on( "click", function( event ){
            event.preventDefault();
            scrollLocation = $( window ).scrollTop();
            window.location.hash = $( event.target ).attr('href').substr(1);
        });
        $( window ).on( "hashchange", function( event ){
            $( window ).scrollTop( scrollLocation );
            if( typeof callback === "function" ){
                callback();
            }
        });
    }
    hashThis( $( ".myAnchor" ), function(){
        // do something useful!
    });
    

  7. 7.음 나는 다소 원유하지만 확실히 작동 방법이있다. 다만 임시 변수의 현재의 스크롤 위치를 저장하고 해시를 변경 한 후에 다시. :)

    음 나는 다소 원유하지만 확실히 작동 방법이있다. 다만 임시 변수의 현재의 스크롤 위치를 저장하고 해시를 변경 한 후에 다시. :)

    원래 그래서 예를 들면 :

    $("#buttons li a").click(function(){
            $("#buttons li a").removeClass('selected');
            $(this).addClass('selected');
    
            var scrollPos = $(document).scrollTop();
            document.location.hash=$(this).attr("id")
            $(document).scrollTop(scrollPos);
    });
    

  8. 8.나는 이것이 가능하다고 생각하지 않습니다. 해시가 페이지 내에서 존재하지 않는 경우 지금까지 내가 아는 한, 브라우저가 변경된 document.location.hash로 이동하지 않는 유일한 시간이다.

    나는 이것이 가능하다고 생각하지 않습니다. 해시가 페이지 내에서 존재하지 않는 경우 지금까지 내가 아는 한, 브라우저가 변경된 document.location.hash로 이동하지 않는 유일한 시간이다.

    이 문서는 직접 질문과 관련, 그러나 그것은 변화 document.location.hash의 일반적인 브라우저 동작에 대해 설명하지 않습니다


  9. 9.당신이 해시 파서 hashchange 이벤트를 사용하는 경우, 당신은 요소의 ID 속성과의 차이를 가지고 하나 개의 문자를 추가 링크 및 변경에 location.hash에 대한 기본 동작을 방지 할 수 있습니다

    당신이 해시 파서 hashchange 이벤트를 사용하는 경우, 당신은 요소의 ID 속성과의 차이를 가지고 하나 개의 문자를 추가 링크 및 변경에 location.hash에 대한 기본 동작을 방지 할 수 있습니다

    $('a[href^=#]').on('click', function(e){
        e.preventDefault();
        location.hash = $(this).attr('href')+'/';
    });
    
    $(window).on('hashchange', function(){
        var a = /^#?chapter(\d+)-section(\d+)\/?$/i.exec(location.hash);
    });
    

  10. 10.더 많은 관련 질문이 모두 여기에 가리키는 중복으로 표시 되었기 때문에이 여기에 추가 ...

    더 많은 관련 질문이 모두 여기에 가리키는 중복으로 표시 되었기 때문에이 여기에 추가 ...

    내 상황은 간단하다 :

    이 방법은 스크롤이 발생하고 위치가 업데이트에는 점프가 없습니다.


  11. 11.이 작업을 수행하는 다른 방법은 뷰포트의 상단에 숨겨진 사업부를 추가하는 것입니다. 이 사업부는 그럼 당신은 스크롤을하지 않습니다 .... 해시가 URL에 추가되기 전에 해시의 ID를 할당됩니다.

    이 작업을 수행하는 다른 방법은 뷰포트의 상단에 숨겨진 사업부를 추가하는 것입니다. 이 사업부는 그럼 당신은 스크롤을하지 않습니다 .... 해시가 URL에 추가되기 전에 해시의 ID를 할당됩니다.


  12. 12.여기에 역사 지원 탭에 대한 내 솔루션입니다 :

    여기에 역사 지원 탭에 대한 내 솔루션입니다 :

        var tabContainer = $(".tabs"),
            tabsContent = tabContainer.find(".tabsection").hide(),
            tabNav = $(".tab-nav"), tabs = tabNav.find("a").on("click", function (e) {
                    e.preventDefault();
                    var href = this.href.split("#")[1]; //mydiv
                    var target = "#" + href; //#myDiv
                    tabs.each(function() {
                        $(this)[0].className = ""; //reset class names
                    });
                    tabsContent.hide();
                    $(this).addClass("active");
                    var $target = $(target).show();
                    if ($target.length === 0) {
                        console.log("Could not find associated tab content for " + target);
                    } 
                    $target.removeAttr("id");
                    // TODO: You could add smooth scroll to element
                    document.location.hash = target;
                    $target.attr("id", href);
                    return false;
                });
    

    그리고 마지막으로 선택한 탭을 표시합니다 :

    var currentHashURL = document.location.hash;
            if (currentHashURL != "") { //a tab was set in hash earlier
                // show selected
                $(currentHashURL).show();
            }
            else { //default to show first tab
                tabsContent.first().show();
            }
            // Now set the tab to active
            tabs.filter("[href*='" + currentHashURL + "']").addClass("active");
    

    참고 * = 필터 통화. 이것은 jQuery를 특정 일이며, 그것없이, 당신의 역사를 사용 탭은 실패합니다.


  13. 13.이 솔루션은 실제 scrollTop에서 사업부를 만들고 해시를 변경 한 후이를 제거합니다 :

    이 솔루션은 실제 scrollTop에서 사업부를 만들고 해시를 변경 한 후이를 제거합니다 :

    $('#menu a').on('click',function(){
        //your anchor event here
        var href = $(this).attr('href');
        window.location.hash = href;
        if(window.location.hash == href)return false;           
        var $jumpTo = $('body').find(href);
        $('body').append(
            $('<div>')
                .attr('id',$jumpTo.attr('id'))
                .addClass('fakeDivForHash')
                .data('realElementForHash',$jumpTo.removeAttr('id'))
                .css({'position':'absolute','top':$(window).scrollTop()})
        );
        window.location.hash = href;    
    });
    $(window).on('hashchange', function(){
        var $fakeDiv = $('.fakeDivForHash');
        if(!$fakeDiv.length)return true;
        $fakeDiv.data('realElementForHash').attr('id',$fakeDiv.attr('id'));
        $fakeDiv.remove();
    });
    

    페이지로드에서 선택, 트리거 앵커 이벤트 :

    $('#menu a[href='+window.location.hash+']').click();
    

  14. 14.나는 나를 위해 작동하는 간단한 방법이있다. 기본적으로, 해시 실제로 HTML에 기억. 그것은 이름 태그 앵커 링크입니다. 이 스크롤 이유 있다고 ... 브라우저는 앵커 링크로 스크롤하려고합니다. 그래서, 하나 줘!

    나는 나를 위해 작동하는 간단한 방법이있다. 기본적으로, 해시 실제로 HTML에 기억. 그것은 이름 태그 앵커 링크입니다. 이 스크롤 이유 있다고 ... 브라우저는 앵커 링크로 스크롤하려고합니다. 그래서, 하나 줘!

     <a name="home"></a><a name="firstsection"></a><a name="secondsection"></a><a name="thirdsection"></a>
        var trimPanel = loadhash.substring(1);    //lose the hash
    
        var dotSelect = '.' + trimPanel;  //replace hash with dot
    
        $(dotSelect).addClass("activepanel").show();        //show the div associated with the hash.
    

    마지막으로, element.preventDefault을 제거하거나 반환 : 거짓과 탐색이 발생 할 수 있습니다. 창은 해시 주소 표시 줄의 URL에 추가됩니다 상단에 남아있을 것입니다, 올바른 패널이 열립니다.


  15. 15.난 당신이 hashchange 전에 위치로 스크롤을 다시 설정해야합니다 생각합니다.

    난 당신이 hashchange 전에 위치로 스크롤을 다시 설정해야합니다 생각합니다.

    $(function(){
        //This emulates a click on the correct button on page load
        if(document.location.hash) {
            $("#buttons li a").removeClass('selected');
            s=$(document.location.hash).addClass('selected').attr("href").replace("javascript:","");
            eval(s);
        }
    
        //Click a button to change the hash
        $("#buttons li a").click(function() {
                var scrollLocation = $(window).scrollTop();
                $("#buttons li a").removeClass('selected');
                $(this).addClass('selected');
                document.location.hash = $(this).attr("id");
                $(window).scrollTop( scrollLocation );
        });
    });
    

  16. 16.페이지에 경우에 당신은 앵커 포인트의 일종으로 ID를 사용하고, 자신 만의 애니메이션 정의를 사용하여 URL의 끝에 #something 추가하고 #something 섹션 페이지 스크롤을 사용자가 원하는 위치 당신은 시나리오를 자바 스크립트 함수, hashchange 이벤트 리스너는 그렇게 할 수 없습니다.

    페이지에 경우에 당신은 앵커 포인트의 일종으로 ID를 사용하고, 자신 만의 애니메이션 정의를 사용하여 URL의 끝에 #something 추가하고 #something 섹션 페이지 스크롤을 사용자가 원하는 위치 당신은 시나리오를 자바 스크립트 함수, hashchange 이벤트 리스너는 그렇게 할 수 없습니다.

    당신은 단순히 예를 들어 hashchange 이벤트 후 즉시 디버거를 넣어 경우,이 같은 (물론, 내가 jQuery를 사용하지만 당신은 요점을 파악) :

    $(window).on('hashchange', function(){debugger});
    

    당신은 당신의 URL을 변경하고 ENTER 버튼을 누르 자마자, 페이지가 즉시 만 그 후, 자신의 정의 스크롤 기능이 트리거 얻을 것이다 해당 섹션에 정지 통지하고, 분류하는 모습 해당 섹션에 스크롤합니다 아주 나쁜.

    나의 제안은 다음과 같습니다

    마지막으로 당신은 당신의 자신의 정의 스크롤 기능에 약간의 트릭을 수행해야합니다

        let hash = window.location.hash.replace(/^#/, '');
        let node = $('#' + hash);
        if (node.length) {
            node.attr('id', '');
        }
        if (node.length) {
            node.attr('id', hash);
        }
    

    태그에 ID를 삭제하고 다시 설정합니다.

    이 트릭을 할해야합니다.


  17. 17.만 준비 문서에 jQuery를이 코드를 추가

    만 준비 문서에 jQuery를이 코드를 추가

    참조 : http://css-tricks.com/snippets/jquery/smooth-scrolling/

    $(function() {
      $('a[href*=#]:not([href=#])').click(function() {
        if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {
          var target = $(this.hash);
          target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
          if (target.length) {
            $('html,body').animate({
              scrollTop: target.offset().top
            }, 1000);
            return false;
          }
        }
      });
    });
    
  18. from https://stackoverflow.com/questions/1489624/modifying-location-hash-without-page-scrolling by cc-by-sa and MIT license