source

Angular에서 앵커 해시 링크를 처리하는 방법JS

manysource 2022. 12. 13. 20:13

Angular에서 앵커 해시 링크를 처리하는 방법JS

AngularJS에서 앵커 해시링크를 어떻게 잘 다루는지 아세요?

간단한 FAQ 페이지에 대한 다음과 같은 마크업이 있습니다.

<a href="#faq-1">Question 1</a>
<a href="#faq-2">Question 2</a>
<a href="#faq-3">Question 3</a>

<h3 id="faq-1">Question 1</h3>
<h3 id="faq-2">Question 2</h3>
<h3 id="fa1-3">Question 3</h3>

위의 링크 중 하나를 클릭할 때 AngularJS가 대행 수신하여 완전히 다른 페이지(링크와 일치하는 루트가 없기 때문에 404 페이지)로 라우팅합니다.

처음에 생각한 것은 "/faq/:chapter"에 일치하는 루트를 생성하여 대응하는 컨트롤러 체크에서$routeParams.chapter일치하는 요소 뒤에 있는 다음 jQuery를 사용하여 아래로 스크롤합니다.

하지만 Angular는JS는 다시 나를 비난하고 페이지 맨 위로 스크롤을 합니다.

여기 있는 사람 중에 과거에 비슷한 일을 한 사람 중에 좋은 해결책을 알고 있는 사람이 있나요?

편집: html5 모드로 전환하면 문제가 해결되지만 IE8+를 지원해야 하기 때문에 권장되는 솔루션이 아닙니다./

를 찾고 있습니다.

여기 (크레이피) 문서가 있습니다.

그리고 여기 소스가 있습니다.

.$location.hash()

app.controller('TestCtrl', function($scope, $location, $anchorScroll) {
   $scope.scrollTo = function(id) {
      $location.hash(id);
      $anchorScroll();
   }
});

<a ng-click="scrollTo('foo')">Foo</a>

<div id="foo">Here you are</div>

여기 시연할 플런커가 있습니다.

EDIT: 라우팅과 함께 사용하려면

각도 루팅을 평소대로 설정한 후 다음 코드를 추가합니다.

app.run(function($rootScope, $location, $anchorScroll, $routeParams) {
  //when the route is changed scroll to the proper element.
  $rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
    $location.hash($routeParams.scrollTo);
    $anchorScroll();  
  });
});

링크는 다음과 같습니다.

<a href="#/test?scrollTo=foo">Test/Foo</a>

다음은 라우팅과 $anchorScroll을 사용한 스크롤을 보여주는 플런커입니다.

더욱 심플한 것은,

app.run(function($rootScope, $location, $anchorScroll) {
  //when the route is changed scroll to the proper element.
  $rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
    if($location.hash()) $anchorScroll();  
  });
});

링크는 다음과 같습니다.

<a href="#/test#foo">Test/Foo</a>

을 알 수 .$location.hash()하다

$scope.scrollTo = function(id) {
    var old = $location.hash();
    $location.hash(id);
    $anchorScroll();
    //reset to old to keep any additional routing logic from kicking in
    $location.hash(old);
};

는 없습니다.또, 다른 은, 「경로」, 「경로」, 「」를 사용하는 만으로 끝납니다.target="_self"

예:

<a href="#faq-1" target="_self">Question 1</a>
<a href="#faq-2" target="_self">Question 2</a>
<a href="#faq-3" target="_self">Question 3</a>

,을 합니다.id다음과 같이 html 요소에 속성을 입력합니다.

<h3 id="faq-1">Question 1</h3>
<h3 id="faq-2">Question 2</h3>
<h3 id="faq-3">Question 3</h3>

코멘트에 기재된 바와 같이 ##을 사용할 필요는 없습니다;-)

<a href="##faq-1">Question 1</a>
<a href="##faq-2">Question 2</a>
<a href="##faq-3">Question 3</a>

<h3 id="faq-1">Question 1</h3>
<h3 id="faq-2">Question 2</h3>
<h3 id="faq-3">Question 3</h3>

경로를 항상 알고 있다면 다음과 같이 앵커를 추가할 수 있습니다.

href="#/route#anchorID

서 ''는route 및 "각도 경로"입니다.anchorID<a id="anchorID">

$anchorScroll이 경우 효과적이지만 Angular의 최신 버전에서 사용하는 훨씬 더 좋은 방법이 있습니다.

그럼 이제 ㅇㅇㅇㄹㄹㄹㄹ,$anchorScroll에 해시를 $location.hash조금도.(정보)

루트에 전혀 영향을 주지 않기 때문에 이것이 최선의 해결책입니다.에 다른 수 .ngRoute를 .이치노$location.hash(id), 명령어음$anchorScroll마법을 부릴 수 있어요

사용법은 다음과 같습니다.먼저 지시 또는 컨트롤러에서 다음을 수행합니다.

$scope.scrollTo = function (id) {
  $anchorScroll(id);  
}

다음으로 뷰에서 다음을 수행합니다.

<a href="" ng-click="scrollTo(id)">Text</a>

또한 고정 네비게이션바(또는 다른 UI)를 고려해야 할 경우 다음과 같이 $anchorScroll 오프셋을 설정할 수 있습니다(메인 모듈의 실행 함수).

.run(function ($anchorScroll) {
   //this will make anchorScroll scroll to the div minus 50px
   $anchorScroll.yOffset = 50;
});

이것은 DOM을 취급하고 있기 때문에 Angular-y라고 생각되는 디렉티브를 사용한 것입니다.

이쪽으로 오세요.

깃헙

코드

angular.module('app', [])
.directive('scrollTo', function ($location, $anchorScroll) {
  return function(scope, element, attrs) {

    element.bind('click', function(event) {
        event.stopPropagation();
        var off = scope.$on('$locationChangeStart', function(ev) {
            off();
            ev.preventDefault();
        });
        var location = attrs.scrollTo;
        $location.hash(location);
        $anchorScroll();
    });

  };
});

HTML

<ul>
  <li><a href="" scroll-to="section1">Section 1</a></li>
  <li><a href="" scroll-to="section2">Section 2</a></li>
</ul>

<h1 id="section1">Hi, I'm section 1</h1>
<p>
Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. 
 Summus brains sit​​, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. 
Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. 
Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.
</p>

<h1 id="section2">I'm totally section 2</h1>
<p>
Zombie ipsum reversus ab viral inferno, nam rick grimes malum cerebro. De carne lumbering animata corpora quaeritis. 
 Summus brains sit​​, morbo vel maleficia? De apocalypsi gorger omero undead survivor dictum mauris. 
Hi mindless mortuis soulless creaturas, imo evil stalking monstra adventus resi dentevil vultus comedat cerebella viventium. 
Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.
</p>

$anchorScroll 서비스를 사용했습니다.해시 변경에 따른 페이지 새로 고침에 대응하기 위해 location Change Start 이벤트를 취소했습니다.도움말 페이지가 ng-switch에 연결되어 있고 새로 고침으로 인해 앱이 고장나기 때문에 이 방법이 효과가 있었습니다.

루트의 .$locationProvider.hashPrefix('!')

완전한 예:

angular.module('app', [])
  .config(['$routeProvider', '$locationProvider', 
    function($routeProvider, $locationProvider){
      $routeProvider.when( ... );
      $locationProvider.hashPrefix('!');
    }
  ])

내 앱의 경로 논리로 이 문제를 해결했습니다.

function config($routeProvider) {
  $routeProvider
    .when('/', {
      templateUrl: '/partials/search.html',
      controller: 'ctrlMain'
    })
    .otherwise({
      // Angular interferes with anchor links, so this function preserves the
      // requested hash while still invoking the default route.
      redirectTo: function() {
        // Strips the leading '#/' from the current hash value.
        var hash = '#' + window.location.hash.replace(/^#\//g, '');
        window.location.hash = hash;
        return '/' + hash;
      }
    });
}

오래된 글이지만, 저는 오랜 시간 동안 다양한 솔루션을 연구해 왔기 때문에 한 가지 더 간단한 글을 공유하고자 합니다. ★★★★★★★★★★★target="_self"<a>그로로고고고고고링크가 기능하고 페이지의 올바른 위치로 이동합니다.

그러나 Angular는 여전히 URL의 #에 이상한 정보를 삽입하기 때문에 이 방법을 사용하면 뒤로 가기 버튼 등을 사용하는 데 문제가 생길 수 있습니다.

일 수 만, 에 「ngView」, 「ngView」, 「ngView」, 「ngView」를 할 수 angular-routengView autoscroll이렇게 '어느 정도'라고 합니다.

ngView(오토스크롤 참조)

(다음 코드는 앵글스트랩에 사용되었습니다)

<!-- use the autoscroll attribute to scroll to hash on $viewContentLoaded -->    
<div ng-view="" autoscroll></div>

<!-- A.href link for bs-scrollspy from angular-strap -->
<!-- A.ngHref for autoscroll on current route without a location change -->
<ul class="nav bs-sidenav">
  <li data-target="#main-html5"><a href="#main-html5" ng-href="##main-html5">HTML5</a></li>
  <li data-target="#main-angular"><a href="#main-angular" ng-href="##main-angular" >Angular</a></li>
  <li data-target="#main-karma"><a href="#main-karma" ng-href="##main-karma">Karma</a></li>
</ul>

나는 이렇게 할 수 있다:

<li>
<a href="#/#about">About</a>
</li>

다음은 특정 요소(하드코드된 "faq" 포함)로 스크롤되는 사용자 지정 지시문을 만드는 데 따른 일종의 더러운 해결 방법입니다.

app.directive('h3', function($routeParams) {
  return {
    restrict: 'E',
    link: function(scope, element, attrs){        
        if ('faq'+$routeParams.v == attrs.id) {
          setTimeout(function() {
             window.scrollTo(0, element[0].offsetTop);
          },1);        
        }
    }
  };
});

http://plnkr.co/edit/Po37JFeP5IsNoz5ZycFs?p=preview

<a href="/#/#faq-1">Question 1</a>
<a href="/#/#faq-2">Question 2</a>
<a href="/#/#faq-3">Question 3</a>

에 들지 않는 ng-click여기 다른 해결책이 있습니다. it용사 it a a를 합니다.filter현재 상태에 따라 올바른 URL을 생성합니다.이 예에서는 ui.router를 사용하고 있습니다.

장점은 링크가 어디로 이동하는지 사용자가 볼 수 있다는 것입니다.

<a href="{{ 'my-element-id' | anchor }}">My element</a>

필터:

.filter('anchor', ['$state', function($state) {
    return function(id) {
        return '/#' + $state.current.url + '#' + id;
    };
}])

ng-route를 사용한 솔루션은 다음과 같은 간단한 지시였습니다.

   app.directive('scrollto',
       function ($anchorScroll,$location) {
            return {
                link: function (scope, element, attrs) {
                    element.click(function (e) {
                        e.preventDefault();
                        $location.hash(attrs["scrollto"]);
                        $anchorScroll();
                    });
                }
            };
    })

html은 다음과 같습니다.

<a href="" scrollTo="yourid">link</a>

anchor Scroll을 사용해 볼 수 있습니다.

컨트롤러는 다음과 같습니다.

app.controller('MainCtrl', function($scope, $location, $anchorScroll, $routeParams) {
  $scope.scrollTo = function(id) {
     $location.hash(id);
     $anchorScroll();
  }
});

그리고 뷰:

<a href="" ng-click="scrollTo('foo')">Scroll to #foo</a>

...앵커 ID에 대한 비밀은 없습니다.

<div id="foo">
  This is #foo
</div>

Angular 앱에서 앵커 opon을 로드하려고 하다가 $route Provider의 URL 재작성 규칙을 발견했습니다.

오랜 실험 끝에 나는 이것을 결정했다.

  1. Angular 앱 모듈의 .run() 섹션에서 document.onload 이벤트 핸들러를 등록합니다.
  2. 몇 가지 문자열 연산을 통해 원래 앵커 태그가 무엇인지 확인합니다.
  3. 위치를 덮어씁니다.($routeProvider는 즉시 "#/" 규칙으로 다시 덮어씁니다.)그러나 괜찮습니다.Angular는 현재 URL 4에서 일어나고 있는 것과 동기화되어 있기 때문에 $anchorScroll()을 호출합니다.

angular.module("bla",[]).}])
.run(function($location, $anchorScroll){
         $(document).ready(function() {
	 if(location.hash && location.hash.length>=1)    		{
			var path = location.hash;
			var potentialAnchor = path.substring(path.lastIndexOf("/")+1);
			if ($("#" + potentialAnchor).length > 0) {   // make sure this hashtag exists in the doc.                          
			    location.hash = potentialAnchor;
			    $anchorScroll();
			}
		}	 
 });

이것이 항상 기능하는지는 모르겠지만, 제 어플리케이션에서는 이것이 예상대로 동작합니다.

ABOUT 페이지에 있고 다음 경로가 있다고 가정합니다.

yourApp.config(['$routeProvider', 
    function($routeProvider) {
        $routeProvider.
            when('/about', {
                templateUrl: 'about.html',
                controller: 'AboutCtrl'
            }).
            otherwise({
                redirectTo: '/'
            });
        }
]);

이제 HTML을 통해

<ul>
    <li><a href="#/about#tab1">First Part</a></li>
    <li><a href="#/about#tab2">Second Part</a></li>
    <li><a href="#/about#tab3">Third Part</a></li>                      
</ul>

<div id="tab1">1</div>
<div id="tab2">2</div>
<div id="tab3">3</div>

결론부터 말하면

앵커가 날 위해 일을 해 주기 전에 페이지 이름을 포함해서요.당신의 생각을 알려주세요.

단점

그러면 페이지가 다시 렌더링되고 앵커로 스크롤됩니다.

갱신하다

더 나은 방법은 다음을 추가하는 것입니다.

<a href="#tab1" onclick="return false;">First Part</a>

스크롤 기능을 쉽게 사용할 수 있습니다.또한 추가 기능으로 애니메이션/스무스 스크롤도 지원합니다.각도 스크롤 라이브러리 세부 정보:

Github - https://github.com/oblador/angular-scroll

바우어:bower install --save angular-scroll

npm:npm install --save angular-scroll

최소 버전 - 9kb만

부드러운 스크롤(애니메이션 스크롤) - 있음

스파이 스크롤 - 네

문서 - 우수

데모 - http://oblador.github.io/angular-scroll/

이게 도움이 됐으면 좋겠다.

https://code.angularjs.org/1.4.10/docs/api/ngRoute/provider/$routeProvider 를 참조해 주세요.

[reloadOnSearch=true] - {location=} - $location만 있을 때 경로를 다시 로드합니다.search() 또는 $location.sarch()가 변경됩니다.

이것을 false로 설정한 것은 위의 모든 것을 생략한 채 성공했습니다.

@Stoyan에 근거해, 다음의 솔루션을 생각해 냈습니다.

app.run(function($location, $anchorScroll){
    var uri = window.location.href;

    if(uri.length >= 4){

        var parts = uri.split('#!#');
        if(parts.length > 1){
            var anchor = parts[parts.length -1];
            $location.hash(anchor);
            $anchorScroll();
        }
    }
});

이렇게 하면 앵커 문제가 해결됩니다.

app.run(function($location, $anchorScroll){
    document.querySelectorAll('a[href^="#"]').forEach(anchor => {
        anchor.addEventListener('click', function (e) {
            e.preventDefault();

            document.querySelector(this.getAttribute('href')).scrollIntoView({
                behavior: 'smooth'
            });
        });
    });
});

경로 변경 시 페이지 맨 위로 스크롤됩니다.

 $scope.$on('$routeChangeSuccess', function () {
      window.scrollTo(0, 0);
  });

이 코드를 컨트롤러에 넣습니다.

@slugslogg는 그것을 가지고 있었지만, 나는 한 가지를 바꾸고 싶다.대신 교환을 사용하므로 다시 설정하지 않아도 됩니다.

$scope.scrollTo = function(id) {
    var old = $location.hash();
    $location.hash(id).replace();
    $anchorScroll();
};

"Replace 메서드"에 대한 문서 검색

위의 솔루션 중 어느 것도 나에게 효과가 없지만, 나는 이것을 시도했고, 그리고 효과가 있었다.

<a href="#/#faq-1">Question 1</a>

그래서 인덱스 페이지부터 시작해서 기존의 앵커를 사용하기 위해 페이지를 통지해야 한다는 것을 깨달았습니다.

angularjs 어플리케이션 해시 네비게이션이 작동하지 않을 수 있으며 부트스트랩 jquery javascript 라이브러리는 이러한 유형의 네비게이션을 광범위하게 사용하여 add를 수행합니다.target="_self"예를 들어 고정 태그 고정.<a data-toggle="tab" href="#id_of_div_to_navigate" target="_self">

AngularJS 1.3.15를 사용하고 있기 때문에 특별히 할 필요가 없어 보입니다.

https://code.angularjs.org/1.3.15/docs/api/ng/provider/$anchorScrollProvider

제 html에서는 다음 내용이 유효합니다.

<ul>
  <li ng-repeat="page in pages"><a ng-href="#{{'id-'+id}}">{{id}}</a>
  </li>
</ul>
<div ng-attr-id="{{'id-'+id}}" </div>

컨트롤러나 JavaScript를 변경할 필요가 전혀 없었습니다.

언급URL : https://stackoverflow.com/questions/14712223/how-to-handle-anchor-hash-linking-in-angularjs