programing

위치를 수정하고 있습니다.페이지 스크롤 없이 해시

telebox 2023. 7. 26. 21:50
반응형

위치를 수정하고 있습니다.페이지 스크롤 없이 해시

Ajax를 사용하여 컨텐츠를 로드하는 페이지가 몇 개 있으며 페이지에 딥 링크해야 하는 경우도 몇 가지 있습니다."사용자"에 대한 링크를 가지고 사람들에게 "설정"을 클릭하라고 말하는 대신 사람들을 user.aspx#설정에 연결할 수 있는 것이 도움이 됩니다.

담당자가 섹션에 대한 올바른 링크를 제공할 수 있도록 함(기술 지원 등)나는 버튼을 클릭할 때마다 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).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=$(this).attr("id")
            //return false;
    });
});

나는 희망했습니다.return false;페이지 스크롤이 중지되지만 링크가 전혀 작동하지 않습니다.이제 설명을 마치겠습니다. 탐색할 수 있도록 말이죠.

아이디어 있어요?

사용하다history.replaceState또는history.pushState해시를 변경합니다.이렇게 하면 관련 요소로 점프가 트리거되지 않습니다.

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

JSFidle 데모

이전 및 이전 지원 기록을 원하는 경우

역사 행위

사중인경우를 .history.pushState(forward할 때 인 것을 하세요.scrollRestoration설정(Chrome 46+에만 해당).

history.scrollRestoration = 'manual';

브라우저 지원

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'd 노드가 마지막으로 표시된 위치를 기준으로 스크롤을 트리거하므로 약간의 도움이 필요합니다.로 합니다야해를 추가해야 합니다.div보기 포트의 맨 위에 있는 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...

꽤 간단한 해결책을 찾은 것 같습니다.문제는 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 "btn_"를 가져옵니다.

저는 최근에 회전목마를 만들고 있었습니다.window.location.hash과 Webkit 않는할 수 했습니다.window.onhashchange이벤트가 발생합니다.

전파를 중지하는 핸들러를 등록하려고 시도하는 경우에도:

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

기본 브라우저 동작을 중지하지 않았습니다.제가 찾은 해결책은 바람직하지 않은 부작용을 유발하지 않고 해시를 변경하는 것이었습니다.

 $("#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;
});

와 "" "" "" 둘 다 수 .my.hashchange:

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

원본 코드의 일부:

$("#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")
});

좋아요, 이것은 꽤 오래된 주제이지만 '올바른' 답이 CSS에서 잘 작동하지 않기 때문에 제가 끼어들고 싶다고 생각했습니다.

이 솔루션은 기본적으로 클릭 이벤트가 페이지를 이동하는 것을 방지하므로 스크롤 위치를 먼저 얻을 수 있습니다.그런 다음 수동으로 해시를 추가하면 브라우저가 자동으로 해시 변경 이벤트를 트리거합니다.해시 변경 이벤트를 캡처하고 올바른 위치로 다시 스크롤합니다.콜백은 해시 해킹을 한 곳에 보관함으로써 코드를 분리하고 지연을 방지합니다.

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!
});

관련 질문이 모두 중복으로 표시되었기 때문에 여기에 추가합니다.

내 상황은 더 단순합니다.

  • 사용자가 링크를 클릭합니다(a[href='#something'])
  • 클릭 핸들러가 수행하는 작업:e.preventDefault()
  • 기능: 부러운스기능롤크드:$("html,body").stop(true,true).animate({ "scrollTop": linkoffset.top }, scrollspeed, "swing" );
  • 그리고나서 window.location = link;

이렇게 하면 스크롤이 발생하고 위치가 업데이트될 때 점프가 발생하지 않습니다.

방법이 . 저, 는다소조잡확만일실있방습다법니이음는하히지하.
한 후 한 후 :) :) 재 스 현 변 후 후 경 재 면 됩 하 니 정 다 설 한 해 를 시 한 저 장 크 위 롤 에 :)

따라서 원본 예제의 경우:

$("#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);
});

해시 파서에 해시 변경 이벤트를 사용하면 링크에 대한 기본 작업을 방지하고 위치를 변경할 수 있습니다.해시 요소의 ID 속성과 차이를 갖도록 문자 하나 추가

$('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);
});
  1. URL 조각을 변경하기 전에 스크롤 위치를 저장합니다.
  2. URL 조각을 변경합니다.
  3. 이전 스크롤 위치를 복원합니다.
let oldScrollPosition = window.scrollY;
window.location.hash = addressFragment;
window.scrollTo(0, oldScrollPosition);

속도가 빠르기 때문에 고객은 아무것도 눈치채지 못할 것입니다.

저는 이것이 가능하다고 생각하지 않습니다.으로 스크롤되지ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅜㅠdocument.location.hash페이지 내에 해시가 존재하지 않는 경우입니다.

이 문서는 질문과 직접적인 관련이 없지만 변경 시 일반적인 브라우저 동작에 대해 설명합니다.document.location.hash

다른 방법은 뷰포트 맨 위에 숨겨진 div를 추가하는 것입니다.그런 다음 이 div는 해시가 url에 추가되기 전에 해시의 ID를 할당받습니다. 그러면 스크롤을 얻을 수 없습니다.

기록 사용 탭에 대한 내 솔루션은 다음과 같습니다.

    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");

에 하십시오.*=에서.filter호출입니다. 이것은 jQuery 고유의 것이며, 이것이 없으면 기록 사용 탭이 실패합니다.

이 솔루션은 실제 scrollTop에서 div를 생성하고 해시를 변경한 후 제거합니다.

$('#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();

저에게 맞는 더 간단한 방법이 있습니다.기본적으로 HTML에서 해시가 실제로 무엇인지 기억하십시오. 이름 태그에 대한 앵커 링크입니다.그래서 스크롤이...브라우저가 앵커 링크로 스크롤하려고 합니다.자, 하나 주세요!

  1. BODY 태그 바로 아래에 버전을 입력합니다.
<a name="home"></a><이름="첫 번째 섹션"></a><이름="두 번째 섹션"></a><이름="세 번째 섹션"></a>
  1. 섹션의 div 이름을 ID 대신 클래스로 지정합니다.

  2. 처리 코드에서 해시 마크를 제거하고 점으로 대체합니다.

var trimPanel = loadhash.sysring(1); //해시 손실
var dot선택 = '.' + trimPanel; // 해시를 점으로 바꿉니다.
$(dotSelect).addClass("활성 패널").show(); // 해시와 관련된 div를 표시합니다.

마지막으로 요소를 제거하고 default.proventDefault 또는 return: false를 반환하고 탐색을 수행합니다.창이 맨 위에 유지되고 해시가 주소 표시줄 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).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 );
    });
});

페이지에서 id를 일종의 앵커 포인트로 사용하고 사용자가 url 끝에 #something을 추가하고 자신이 정의한 애니메이션 javascript 함수를 사용하여 페이지를 해당 #something 섹션으로 스크롤하도록 하는 시나리오가 있는 경우 해시 변경 이벤트 수신기는 이를 수행할 수 없습니다.

예를 들어, 해시 변경 이벤트 직후에 디버거를 넣는다면 다음과 같습니다(글쎄요, 저는 jquery를 사용하지만 요점을 알 수 있습니다).

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

URL을 변경하고 Enter 버튼을 누르면 페이지가 해당 섹션에서 즉시 중지되고, 그 후에만 정의된 스크롤 기능이 트리거되어 해당 섹션으로 스크롤됩니다. 이는 매우 불량해 보입니다.

제 제안은 다음과 같습니다.

  1. 스크롤할 섹션의 앵커 포인트로 ID를 사용하지 마십시오.

  2. 만약 당신이 아이디를 사용해야 한다면, 나처럼.대신 'popstate' 이벤트 수신기를 사용하면 URL에 추가한 바로 그 섹션으로 자동으로 스크롤되지 않고 대신 popstate 이벤트 내에서 자신의 정의된 함수를 호출할 수 있습니다.

    $(window).on('popstate', function(){myscrollfunction()});

마지막으로 정의된 스크롤 기능에서 비트 트릭을 수행해야 합니다.

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

태그의 ID를 삭제하고 재설정합니다.

이 정도면 효과가 있을 겁니다.

이것은 replaceState를 사용하는 데 효과가 있었습니다.

$('a[href^="#"]').click(function(){
    history.replaceState({}, '', location.toString().replace(/#.*$/, '') + $(this).attr('href'));
});

이 코드를 문서 준비 시 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;
      }
    }
  });
});

언급URL : https://stackoverflow.com/questions/1489624/modifying-location-hash-without-page-scrolling

반응형