Подтвердить что ты не робот

Как предотвратить перенаправление <a href= "https://stackoverflow.com/#something" rel="nofollow noreferrer" >в Angular Js1.2

Я использовал AngularJs-1.0.7 и Bootstrap в своем приложении. Недавно я перешел из AngularJs-1.0.7 в AngularJs-1.2. Я использую Bootstrap Accordions и Tabs.

Код HTML для вкладки содержит <a href="#id_for_content">, как показано ниже.

<ul id="myTab" class="nav nav-tabs">
    <li class="active"><a href="#firstTab" data-toggle="tab">Home</a></li>
    <li><a href="#secondTab" data-toggle="tab">Profile</a></li>
</ul>

<div id="myTabContent" class="tab-content">
    <div class="tab-pane fade in active" id="firstTab">
      <p>Content for first tab.</p>
    </div>
    <div class="tab-pane fade" id="secondTab">
      <p>Content For second tab.</p>
    </div>
</div>

В старых версиях Angular изменение маршрута происходит, только если мы даем якорный тег, например <a href="#/firstTab">. Но AngularJs-1.2 перенаправляет <a href="#firstTab">. Он не учитывает / между # и firstTab. Следовательно, при нажатии на Tab он перенаправляется на http://web_url/#/firstTab. Как решить эту проблему?


Мое решение

Я нашел решение для этой проблемы. Я написал директиву для тега. В этой директиве я проверил атрибут href. Если он соответствует, предотвращает его поведение по умолчанию. Проверьте следующий код.

app.directive('a', function() {
    return {
        restrict: 'E',
        link: function(scope, elem, attrs) {
            if(attrs.href === '#firstTab'|| attrs.href === '#secondTab'){
                elem.on('click', function(e){
                    e.preventDefault();
                });
            }
        }
   };
}); 

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

Если вы можете найти лучшее решение, дайте нам знать об этом.

4b9b3361

Ответ 1

Просто добавьте это в свои ссылки:

target="_self"

И вы готовы;)

Ответ 2

попробуйте data-target="#something", он отлично работает для меня как в среде разработки, так и в производственной среде.

Ответ 3

Я просто хотел бы сообщить вам, что есть еще одно решение для решения этой проблемы (без определения функции в контроллерах).

Вы можете создать директиву, которая предотвратит поведение браузера по умолчанию (которое фактически меняет URL):

var PreventDefault = function () {

    var linkFn = function (scope, element, attrs) {
        $(element).on("click", function (event){
            event.preventDefault();
        });
    };

    return {
        restrict: 'A',
        link: linkFn
    }
};

а затем просто добавьте директиву в каждый элемент a, ответственный за переключение табуляции:

<ul id="myTab" class="nav nav-tabs">
    <li class="active"><a href="#firstTab" prevent-default data-toggle="tab">Home</a></li>
    <li><a href="#secondTab" prevent-default data-toggle="tab">Profile</a></li>
</ul>

<div id="myTabContent" class="tab-content">
    <div class="tab-pane fade in active" id="firstTab">
      <p>Content for first tab.</p>
    </div>
    <div class="tab-pane fade" id="secondTab">
      <p>Content For second tab.</p>
    </div>
</div>

Ответ 4

В общем, вы можете определить функции на прототипе всех областей с помощью корнеплодов. Добавьте ng-click на ваши якорные теги и передать $event обработчикам корневых объектов. Angular может отправить исходное событие также с помощью ng-click:

<a ng-click="tabclick($event)">

в блоке запуска вашего модуля вы можете установить функцию tabClick на $rootScope

$rootScope.tabclick = function ($event) { $event.preventDefault(); }

Это будет работать для любых областей, и вам не придется проверять определенные идентификаторы элементов.

Пример скрипта: http://jsfiddle.net/stto3703/wQe6P/

Приветствия

Ответ 5

Вы можете использовать ng-click для вызова функции в вашей JS. В этой функции используйте метод preventDefault и используйте метод $location hash для изменения хэша в вашем URL-адресе.

Ответ 6

У меня была эта проблема и сейчас, и я только наткнулся на этот вопрос (и ваш собственный ответ). Оказывается, вы почти правы с вашим решением, просто небольшая модификация заставляет его работать так, как вам хотелось бы.

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

Итак, небольшая модификация вашего кода для проверки наличия атрибута 'toggle' решает его для меня:

app.directive('a', function() {
    return {
        restrict: 'E',
        link: function(scope, elem, attrs) {
            if(attrs.toggle){
                elem.on('click', function(e){
                    e.preventDefault();
                });
            }
        }
   };
});

Надеюсь, это поможет!

Ответ 7

Ваше решение в вашем вопросе действительно работает, но для предотвращения проверки каждого идентификатора привязки измените

if (attrs.href === '#firstTab'|| attrs.href === '#secondTab')

к

if (attrs.href && attrs.href.indexOf('#') > -1)

Директива

.directive('a', function () {
    return {
        restrict: 'E',
        link: function (scope, elem, attrs) {
            if (attrs.href && attrs.href.indexOf('#') > -1) {
                elem.on('click', function (e) {
                    e.preventDefault();
                });
            }
        }
    };
})  

Ответ 8

кредиты https://prerender.io/js-seo/angularjs-seo-get-your-site-indexed-and-to-the-top-of-the-search-results/

Мое решение:  - внутри app.js попробуйте добавить "$ locationProvider.hashPrefix('!');"

    .config(['$stateProvider', '$urlRouterProvider', '$httpProvider', '$locationProvider',
    function($stateProvider, $urlRouterProvider, $httpProvider, $locationProvider) {
    $stateProvider
    .state('menu', {
        url: '/',
        cache: false,
        abstract: true,
        templateUrl: 'static/www/templates/menu.html'
    })
    .state('menu.main_page', {
    url: 'app/main',
    cache: false,
    views: {
        'menuContent': {
          templateUrl: 'static/www/templates/mainpage.html',
          controller: 'MainCtrl'
        }
    }
    })
    $locationProvider.hashPrefix('!');
    $urlRouterProvider.otherwise(function ($injector, $location) {
        var $state = $injector.get('$state');
        $state.go('menu.mainpage');
    });
   }])
  • внутри index.html попробуйте добавить

    <meta name="fragment" content="!">

и как Марсель, упомянутый выше

.directive('a', function () {
return {
    restrict: 'E',
    link: function (scope, elem, attrs) {
        if (attrs.href && attrs.href.indexOf('#') > -1) {
            elem.on('click', function (e) {
                e.preventDefault();
            });
        }
    }
};
})

что все! работает для меня!

Ответ 9

Если вы не добились успеха в предыдущих ответах, вы можете попробовать использовать $timeout... В этом случае я использовал вкладки AngularUI...

vm.removeUserTab = function (user) {
    $timeout(function () {
        vm.activeTab = 0;
        var index = vm.userTabs.indexOf(user);
        vm.userTabs.splice(index, 1);
    });
};