[javascript] AngularJS에서 앵커 해시 링크를 처리하는 방법

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를 사용하여 아래로 스크롤하는 것입니다.

그러나 AngularJS는 다시 나를 괴롭 히고 어쨌든 페이지 상단으로 스크롤합니다.

그래서 여기에 누군가가 과거에 비슷한 일을하고 그것에 대한 좋은 해결책을 알고 있습니까?

편집 : html5Mode로 전환하면 문제가 해결되지만 어쨌든 IE8 +를 지원해야하므로 허용되는 솔루션이 아니라고 두려워합니다.



답변

찾고 있습니다 $anchorScroll().

다음은 (크 래피) 설명서입니다.

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

기본적으로 컨트롤러에 주입하고 호출하면 ID가있는 모든 요소로 스크롤됩니다. $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>

여기에 설명하는 플런저가 있습니다.

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

평소대로 각도 라우팅을 설정 한 후 다음 코드를 추가하십시오.

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을 사용한 스크롤을 보여주는 Plunker입니다.

그리고 더 간단합니다.

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>

그리고 다음과 같이 html 요소 의 id속성을 사용하십시오 .

<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 인 지시문을 사용하는 솔루션이었습니다.

여기에 Plnkr

깃 허브

암호

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 서비스를 사용했습니다. 해시 변경과 함께 진행되는 페이지 새로 고침을 막기 위해 locationChangeStart 이벤트를 취소했습니다. 도움말 페이지가 ng-switch에 연결되어 있고 새로 고침이 앱을 본질적으로 손상시킬 수 있기 때문에 이것은 나를 위해 일했습니다.