Удалить событие hashchange из Angular или предотвратить Angular от перезаписи якорных ссылок
У нас есть проект, который использует Angular, но только для аспекта привязки к UI/AJAX, а не для каких-либо функций маршрутизации или SPA.
Мы хотим использовать якорные ссылки (#section-2
) в статьях, которые мы пишем в выбранной нами CMS, а также использовать привязывающие ссылки с других страниц (/my-page#section-C
), но Angular переписывает их на #/section-2
, который разбивает якорные ссылки, созданные CMS.
Невозможно увеличить CMS, чтобы изменить способ обработки привязных ссылок.
Возможно ли это:
-
Удалить привязку события hashchange
из Angular? Я вижу, что это событие привязано к исходному файлу src/ng/browser.js
, где он обрабатывает некоторые из маршрутизации и переписывания ссылок, но он находится внутри закрытия, поэтому он не может быть доступен напрямую (и мы связываемся с Angular с CDN поэтому невозможно изменить источник Angular, и мы не хотим поддерживать собственный "пользовательский" Angular источник).
-
Задайте опцию или вызовите метод конфигурации, который в конечном счете отключит весь аспект маршрутизации Angular и не позволяет переписывать какие-либо ссылки? (Или, есть ли способ не включать эту часть Angular, но все же сохранить функциональность контроллера /UI/AJAX?)
Заметьте, что я уже пробовал это:
$locationProvider.html5Mode(true)
Однако он делает все другие ссылки на сайте неработоспособными, потому что все ссылки передаются через Angular для обработки. Поэтому, если я ссылаюсь на домашнюю страницу (<a href="/">Home</a>
) и нажимаю ссылку на html5mode
on, ссылка ничего не делает.
Ответы
Ответ 1
Как обходной путь (и, конечно, не лучшая практика), я закончил модификацию источника Angular, чтобы удалить переписывание URL.
Я сделал несколько изменений, но я считаю, что тот, который заставил ссылки привязки работать снова, добавлял оператор return;
в строке 844 location.js
в источнике Angular:
https://github.com/angular/angular.js/blob/master/src/ng/location.js#L844
Это короткое замыкание вокруг большей части функций перезаписи URL.
Я также полностью удалил строки 262-264 из browser.js
, который удаляет крюк Angular в событии hashchange
:
https://github.com/angular/angular.js/blob/master/src/ng/browser.js#L262-264
Это не повлияло ни на одну из функций привязки Angular, но это заставило ссылки привязки снова начать работать.
Ответ 2
Я считаю, что вы хотите $anchorScroll. См. Этот ответ: Как обрабатывать привязку привязки привязки в AngularJS
Вот пример того, как он будет работать. Хэш просто рассматривается как часть идентификатора:
app.controller('TestCtrl', function($location, $anchorScroll) {
var vm = this;
vm.scrollTo = function(id) {
$location.hash(id);
$anchorScroll();
}
});
<a ng-click="vm.scrollTo('#foo')">Foo</a>
<div id="#foo">Here you are</div>
См. plunker, демонстрирующий $anchorScroll
С помощью маршрутизации вы можете изменить ссылку на:
<a href="#/test##foo">Test/Foo</a>
и добавьте это в конфигурацию запуска:
$rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
if($location.hash()) {
$anchorScroll();
}
});
Смотрите plunker, демонстрирующий прокрутку с маршрутизацией и $anchorScroll
Ответ 3
Angular $locationProvider.html5Mode с этим параметром rewriteLinks
- это то, что вы ищете. Он поместит angular в режим, в котором $location все еще может использоваться для чтения и записи URL-адреса браузера, но он никогда не попытается захватить ссылки на клики и запустить маршрутизацию angular SPA.
например:
$locationProvider.html5Mode({
enabled: true,
requireBase: false,
rewriteLinks: false
});
Ответ 4
После установки $locationProvider.html5Mode (true) вы также установили <base>
в <head>
вашего документа?
<html>
<head>
<base href="/">
</head>
</html>
Посмотрите здесь:
"Есть 2 вещи, которые нужно сделать.
- Настройка $locationProvider
- Настройка базы для относительных ссылок
или здесь
Ответ 5
У меня была аналогичная проблема при использовании angular с wordpress и найдено действительно простое исправление. Все, что вам нужно сделать, это удалить все $location injection в контроллерах. Когда вы вводите $location service (независимо от того, используете вы его или нет), он захватывает # поведение.
Это означает, что вам нужно прокручивать все ваши контроллеры, директивы и т.д. и убедитесь, что служба определения местоположения не указана нигде.
НТН
Ответ 6
Но почему бы не использовать ng-route? это полностью решит ваши проблемы. используя Ng-маршруты, вы можете достичь следующего (что вам и нужно).
<a href="#" onclick="location.href='http://www.example.com/base/#section-A'; return false;"> Section A</a>
<a href="#" onclick="location.href='http://www.example.com/base/my-page#section-C'; return false;">Another page</a>
<a href="/other-base/another?search">external</a>
вот фрагмент app.js
app.config(function($locationProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');
})
Переписывание HTML-ссылок
При использовании режима API истории HTML5 вам не понадобятся специальные ссылки hashbang. Все, что вам нужно сделать, это указать регулярные URL-ссылки, например: <a href="/some?foo=bar">link</a>
Когда пользователь нажимает на эту ссылку,
В устаревшем браузере URL-адрес изменяется на /index.html#!/some?foo=bar
В современном браузере URL-адрес изменяется на /some?foo=bar
В следующих случаях ссылки не переписываются; вместо этого браузер выполнит полную перезагрузку страницы по исходной ссылке.
Ссылки, содержащие целевой элемент
Пример: <a href="/ext/link?a=b" target="_self">link</a>
Абсолютные ссылки, которые переходят в другой домен
Пример: <a href="#" onclick="location.href='http://angularjs.org/'; return false;">link</a>
Ссылки, начинающиеся с '/', которые приводят к другому базовому пути
Пример: <a href="/not-my-base/link">link</a>
Относительные ссылки
Обязательно проверьте все относительные ссылки, изображения, скрипты и т.д. Angular требует указать базу url в заголовке основного файла html (<base href="/my-base/index.html">
), если для html5Mode.requireBase не установлено значение false в html5Mode объект определения передан в $locationProvider.html5Mode(). При этом относительные URL-адреса всегда будут разрешены для этого базового URL-адреса, даже если исходный URL-адрес документа отличается.
Есть одно исключение: ссылки, содержащие только хэш-фрагмент (например, <a href="#target">
), будут изменять значение $location.hash() и не изменять URL-адрес в противном случае. Это полезно для прокрутки к якорям на одной странице без необходимости знать, на какой странице находится пользователь.
Серверная сторона
Использование этого режима требует перезаписи URL-адресов на стороне сервера, в основном вы должны переписать все свои ссылки на точку входа вашего приложения (например, index.html). Требование к тегу также важно для этого случая, так как позволяет Angular различать часть URL-адреса, которая является базой приложения, и путь, который должен обрабатывать приложение.
ngSource