AngularJs с хешем в href прерывает прокрутку и преобразует URL в hash+fwslash+id

Как настроить AngularJs для прокрутки к элементу привязки, указанному в href с #id?

Эта проблема

Якорная ссылка с хешем, напр. href="# Recommended" становится url#/ Recommended вместо url # Recommended, поэтому он не будет прокручиваться, как ожидалось. Если библиотека angularjs не загружена, она работает нормально. В строке состояния, когда я перемещаю курсор в верхней части ссылки, строка состояния браузера правильно отображает ссылку, которую я собираюсь открыть, но после нажатия она преобразуется и не будет правильно прокручиваться. Я не использую угловые маршруты.

Отрывки из моего кода AngularJS, которые могут мешать манипуляциям с прокруткой / js:

...
app.config([ '$httpProvider', '$compileProvider', function($httpProvider, $compileProvider) {
    $compileProvider.debugInfoEnabled(false);
    // Initialize get if not there
    if (!$httpProvider.defaults.headers.get) {
        $httpProvider.defaults.headers.get = {};
    }

    // Disable IE ajax request caching
    $httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
} ]);
...
app.directive('jumpForm', function($timeout) {
    return {
        restrict : 'A',
        link : function(scope, elem) {

            // set up event handler on the form element
            elem.on('submit', function() {
                $timeout(function() {
                    // find the first invalid element
                    var firstInvalid = elem[0].querySelector('.has-error');

                    // if we find one, set focus
                    if (firstInvalid) {

                        $('html, body').animate({
                            duration : 2000,
                            scrollTop : (firstInvalid.offsetTop + 100)
                        });
                    }
                }, 200);

            });
        }
    };
});
...
app.factory('httpResponseInterceptor', [ '$q', '$location', '$window', function($q, $location, $window) {
    return {
        response : function(response) {
            if (response && response.data && response.data.errorCode == 'AUTHENTICATION_REQUIRED') {
                var _context = $("body").attr("data-context");
                var redirectUrl = _context + '/registration?msg=session_expired';
                $window.location.href = redirectUrl;
                return $q.reject(response);
            }
            return response;
        }
    }
} ]);

app.config([ '$httpProvider', function($httpProvider) {
    $httpProvider.interceptors.push('httpResponseInterceptor');
} ]);

Вызов с хэштегом:

<a href="#recommanded"> </a>

Испытания и ошибки

Внутренние обходные пути

anchorScroll

В теме Как обрабатывать привязку хеш-ссылок в AngularJS рекомендуется вставить этот фрагмент:

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

И называя это:

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

Это приводит к тому, что на консоли не возникает ошибка, а происходит то же поведение, что и раньше. URL преобразуется без прокрутки на якорь. Кроме того, мне не нравится идея, что в итоге у меня будет функция ng-click для этого.

Добавил мои angularjs с:

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#recommanded">Test/Foo</a>

В результате нет ошибок, но не работает ни прокрутка.

Некоторые намекают просто сделать #/# рекомендуемое в href. Используйте target="_self". Никто из них не сработал для меня.

Внешние обходные решения

Директива scrollTo

   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="recommanded">link</a>

Это на самом деле работает, но предпочло бы решение, где вызов href = "# рекомендуемый" просто работает. Или хотя бы оживить свиток.

du-smooth-scroll углового свитка

Добавил duScroll в мой angularApp.js: var app = angular.module('app', [ ..., 'duScroll' ]);У меня есть файл angular-scroll.min.js, загруженный на странице с angularApp.js без ошибок. Я звоню <a du-smooth-scroll href="#recommended-to-you">recommanded</a> для существующего div с этим идентификатором. Но он ничего не сделает, никаких ошибок, но не будет двигаться. Попробовал модуль duScroll с добавлением явных настроек продолжительности замедления и т. Д., Ошибок нет, но не работает.

1 ответ

Решение

html5Mode

Как описано в угловом добавлении косой черты перед хешем в URL, я попытался включить режим html5, добавив:

app.config(function($locationProvider) {
          $locationProvider.html5Mode(true);
        })

Я установил базовый тег в разделе заголовка.

Эти настройки позволили ему начать работать как положено.

... но я бы упомянул, что после того, как местоположение в адресной строке будет обновлено до ссылочного хэша, если я снова нажму на ссылку, оно просто немного опустится, а не к указанному местоположению. При нажатии на ссылки с разными якорями это работает хорошо. Не уверен, что это общая ошибка или только некоторые из моих настроек имеют неприятные последствия.

Другие вопросы по тегам