Якірні посилання в Angularjs?


78

Чи можна використовувати якірні посилання з Angularjs?

Тобто:

 <a href="#top">Top</a>
 <a href="#middle">Middle</a>
 <a href="#bottom">Bottom</a>

 <div name="top"></div>
 ...
 <div name="middle"></div>
 ...
 <div name="bottom"></div>

Дякую


13
Ну, Angularjs перехоплює ці посилання і направляє їх через власну систему маршрутизації ...
Андрій Дроздюк

Відповіді:


105

Є кілька способів зробити це, здається.

Варіант 1: Рідний кутовий

Angular надає $anchorScrollпослугу, але документації дуже бракує, і я не зміг змусити її працювати.

Перегляньте http://www.benlesh.com/2013/02/angular-js-scrolling-to-element-by-id.html, щоб отримати деяке розуміння $anchorScroll.

Варіант 2: Спеціальна директива / Власний JavaScript

Іншим способом, який я перевірив, було створення користувацької директиви та використання el.scrollIntoView(). Це працює досить пристойно, в основному роблячи наступне у вашій функції посилання на директиви:

var el = document.getElementById(attrs.href);
el.scrollIntoView();

Однак, здається, трохи перебільшено робити обидва ці дії, коли браузер спочатку підтримує це, чи не так?

Варіант 3: Angular Override / Native Browser

Якщо ви подивитесь на http://docs.angularjs.org/guide/dev_guide.services.$location та його розділ Перезапис посилань HTML, то побачите, що посилання не переписуються в наступному:

Посилання, що містять цільовий елемент

Приклад: <a href="https://stackoverflow.com/ext/link?a=b" target="_self">link</a>

Отже, все, що вам потрібно зробити, - це додати targetатрибут до своїх посилань, приблизно так:

<a href="#anchorLinkID" target="_self">Go to inpage section</a>

Кутові значення за замовчуванням для браузера, а оскільки його прив'язка, а не інша базова URL-адреса, браузер прокручується до потрібного місця за бажанням.

Я вибрав варіант 3, оскільки тут найкраще покластись на функціональність власного браузера та економить час та сили.

Потрібно зауважити, що після успішної зміни прокрутки та хешу Angular виконує подальші дії та переписує хеш у свій власний стиль. Однак браузер вже завершив свій бізнес, і ви готові піти.


1
На жаль, в адресному рядку є багато залишків побічних ефектів від зайвого хешу. Я знайшов тут варіант 2 набагато ефективнішим. Хтось уже написав директиву для завантаження: ngmodules.org/modules/ngScrollTo
Riley Lark,

Варіант 2 тут, безумовно, найпростіший, особливо якщо ви використовуєте маршрутизацію. У мене була проблема з шаруватими вкладками за допомогою Bootstrap, і Opt2 зробив це по-дурному просто. Дякую
Дамео,

4
Є одна проблема із встановленням цілі = "_ self". Якщо я дам комусь щось на зразок цього посилання stackoverflow.com/#footer , він не перейде до нижнього колонтитула. Він переходить до нижнього колонтитула, лише якщо натиснути <a href="#footer" target="_self"> Перейти до нижнього колонтитула </a>. Будь-який ідеал? Це важливо, оскільки я зазвичай даю своєму другові таке посилання, щоб показати, на якій частині йому / їй потрібно зосередитися.
Райан

3
На жаль, варіант 3 перенаправить мене до кореневої сторінки веб-сайту .ie localhost: 9000 / # medical замість localhost: 9000 / # / case / 1 # medical . навіть з ціллю _self.
Рафаель

1
Варіант 3 фантастично працював для посилання "перейти до вмісту"! Дякую!
Lane Sawyer

27

Я не знаю, чи відповідає це на ваше запитання, але так, ви можете використовувати посилання angularjs, такі як:

<a ng-href="http://www.gravatar.com/avatar/{{hash}}"/>

Є хороший приклад на веб-сайті AngularJS:

http://docs.angularjs.org/api/ng.directive:ngHref

ОНОВЛЕННЯ: Документація AngularJS була трохи неясною, і вона не надала хорошого рішення для неї. Вибачте!

Ви можете знайти найкраще рішення тут: Як обробити прив'язку хеш-хешу в AngularJS


Я ні @drozzy: не могли б ви сказати нам, яку версію AngularJS ви використовували? спасибі
Анас

1
Фокус у тому, щоб мати порожній атрибут href. Ви, хлопці, робите це?
Андрій Дроздюк

1
Де задокументовано, що крім використання ng-href нам також потрібно мати порожній href?
alearg

Це друге посилання спрацювало, вам навіть не потрібно турбуватися про маршрутизацію, якщо воно знаходиться на одній сторінці. Працював чудово.
Мастро

24

Ви можете спробувати використовувати anchorScroll .

Приклад

Отже, контролером буде:

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>

... і не секрет для ідентифікатора якоря:

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

2
Примітка: $anchorScroll()дзвінок після $location.hash()дзвінка непотрібний, оскільки $anchorScrollспостерігає $location.hashавтоматично ().
PLPeeters

Документи називають $ anchorScroll () у своєму прикладі, але @Edmar ви маєте рацію, пропускаючи $anchorScroll()все ще прокрутки до нового місця.
twknab

7

$ anchorScroll справді є відповіддю на це, але є набагато кращий спосіб використовувати його в останніх версіях Angular.

Тепер $ anchorScroll приймає хеш як необов’язковий аргумент, тому вам зовсім не потрібно змінювати $ location.hash. ( документація )

Це найкраще рішення, оскільки воно взагалі не впливає на маршрут. Я не міг змусити працювати жодне з інших рішень, оскільки я використовую ngRoute, і маршрут перезавантажиться, як тільки я встановлю $location.hash(id), перш ніж $ anchorScroll зможе зробити свою магію.

Ось як це використовувати ... по-перше, в директиві або контролері:

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

а потім у поданні:

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

Крім того, якщо вам потрібно врахувати фіксовану панель навігації (або інший інтерфейс користувача), ви можете встановити зсув для $ anchorScroll таким чином (у функції запуску головного модуля):

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


1

Працює для мене:

 <a onclick='return false;' href="" class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" ng-href="#profile#collapse{{$index}}"> blalba </a>

1

Вам потрібно лише додати target = "_ self" до свого посилання

напр. <a href="#services" target="_self">Services</a><div id="services"></div>


Перевірено на angular.js / 1.6.10 і працює нормально, щоб було зрозуміліше. Я відредагував відповідь
Farzad.Kamali

може щось створити конфлікт? У мене точно такий самий код
Дані

0

Або ви можете просто написати:

ng-href="\#yourAnchorId"

Зверніть увагу на зворотну скісну риску перед символом хешу


Ні, я просто придумав це рішення випадково.
Марко

хтось перевіряв, чи це працює, чи це має працювати?
JustGoscha

ng-href="##anchorId"працює для мене (Angular 1.2.21). Ось що я помітив $ location.hash ('anchorId').
PSWai,

9
ng-href = "\ # myAnchorTag" у мене не працював, як і ng-href = "## anchorId"
mcgraw

0

Якщо ви використовуєте SharePoint і angular, зробіть це, як показано нижче:

<a ng-href="{{item.LinkTo.Url}}" target="_blank" ng-bind="item.Title;" ></a> 

де LinkTo та Title - стовпець SharePoint.


0

Найкращим вибором для мене було створити директиву для виконання роботи, тому що, $location.hash()і $anchorScroll()викрасти URL-адресу, створивши багато проблем для моєї маршрутизації SPA.

MyModule.directive('myAnchor', function() {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function(scope, elem, attrs, ngModel) {
      return elem.bind('click', function() {
        //other stuff ...
        var el;
        el = document.getElementById(attrs['myAnchor']);
        return el.scrollIntoView();
      });      
    }
  };
});

0

Ви також можете перейти до ідентифікатора HTML з внутрішнього контролера

$location.hash('id_in_html');
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.