Как предотвратить обнаружение меток привязки?

Скажем, у меня есть якорный тег, например

<a href="#" ng-click="do()">Click</a>

Как я могу запретить браузеру переходить на # в AngularJS?

Ответ 1

ОБНОВЛЕНИЕ. С тех пор я решил изменить это решение. После большего развития и времени, потраченного на это, я считаю, что лучшим решением этой проблемы является следующее:

<a ng-click="myFunction()">Click Here</a>

И затем обновите свой css, чтобы получить дополнительное правило:

a[ng-click]{
    cursor: pointer;
}

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


Следующее - это мое предыдущее решение, которое я оставляю здесь только для устаревших целей:

Если у вас возникла эта проблема, простая директива, которая устраняет эту проблему, такова:

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

Он проверяет все теги привязки (<a></a>), чтобы узнать, является ли их атрибут href пустой строкой ("") или хешем ('#') или существует назначение ng-click. Если он найдет какое-либо из этих условий, он поймает событие и предотвратит поведение по умолчанию.

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

Ответ 2

В соответствии с docs для ngHref вы должны уйти с href или do href= "".

<input ng-model="value" /><br />
<a id="link-1" href ng-click="value = 1">link 1</a> (link, don't reload)<br />
<a id="link-2" href="" ng-click="value = 2">link 2</a> (link, don't reload)<br />
<a id="link-4" href="" name="xx" ng-click="value = 4">anchor</a> (link, don't reload)<br />
<a id="link-5" name="xxx" ng-click="value = 5">anchor</a> (no link)<br />

Ответ 3

Вы можете передать объект $event вашему методу и вызвать $event.preventDefault() на нем, чтобы обработка по умолчанию не выполнялась:

<a href="#" ng-click="do($event)">Click</a>

// then in your controller.do($event) method
$event.preventDefault()

Ответ 4

Я предпочитаю использовать директивы для такого рода вещей. Вот пример

<a href="#" ng-click="do()" eat-click>Click Me</a>

И код директивы для eat-click:

module.directive('eatClick', function() {
    return function(scope, element, attrs) {
        $(element).click(function(event) {
            event.preventDefault();
        });
    }
})

Теперь вы можете добавить атрибут eat-click к любому элементу, и он автоматически получит preventDefault() '.

Преимущества:

  • Вам не нужно передавать уродливый объект $event в вашу do() функцию.
  • Ваш контроллер более подвержен тестированию, потому что ему не нужно вырезать $event.object

Ответ 5

Хотя Рено дал отличное решение

<a href="#" ng-click="do(); $event.preventDefault()">Click</a> 

Я лично нашел, что вам также нужно $event.stopPropagation() в некоторых случаях, чтобы избежать некоторых побочных эффектов

<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">
    Click</a>

будет моим решением

Ответ 6

Самое легкое решение, которое я нашел, это:

<a href="#" ng-click="do(); $event.preventDefault()">Click</a>

Ответ 7

ng-click="$event.preventDefault()"

Ответ 8

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

Итак, вот два способа решить эту проблему, не добавляя курсора: стиль указателя:

  • Используйте javascript:void(0) вместо #:

    <a href="javascript:void(0)" ng-click="doSomething()">Do Something</a>
    
  • Используйте $event.preventDefault() в директиве ng-click (чтобы вы не загружали ваш контроллер ссылками, связанными с DOM):

    <a href="#dontGoHere" ng-click="doSomething(); $event.preventDefault()">Do Something</a>
    

Лично я предпочитаю первого над последним. javascript:void(0) имеет другие преимущества, которые обсуждаются здесь. Существует также обсуждение "ненавязчивого JavaScript" в этой ссылке, которая пугающе недавно, и не обязательно непосредственно относится к приложению angular.

Ответ 9

Вы можете сделать следующее:

1.Удалить атрибут href из тега anchor (a)

2. Установить курсор указателя в элементах css для ng click

 [ng-click],
 [data-ng-click],
 [x-ng-click] {
     cursor: pointer;
 }

Ответ 10

HTML

здесь pure angularjs: рядом с функцией ng-click вы можете написать функцию preventDefault(), разделив точку с запятой

<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">Click me</a>

JS

$scope.do = function() {
    alert("do here anything..");
}

(или)

вы можете продолжить этот путь, это уже обсуждается здесь.

HTML

<a href="#" ng-click="do()">Click me</a>

JS

$scope.do = function(event) {
    event.preventDefault();
    event.stopPropagation()
}

Ответ 11

Поскольку вы создаете веб-приложение, почему вам нужны ссылки?

Поменяйте привязки на кнопки!

<button ng-click="do()"></button>

Ответ 12

если все еще актуально:

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

...

scope.unselect = function( event ) {
 event.preventDefault();
 event.stopPropagation();
}

...

Ответ 13

Попробуйте этот параметр, который я вижу, еще не указан выше:

<a href="" ng-click="do()">Click</a>

Ответ 14

Я бы пошел с:

<a ng-click="do()">Click</a>
  • потому что в соответствии с документами вы можете уйти из href, а затем Angular будет обрабатывать предупреждение по умолчанию для вас!

Все это предотвращает меня по умолчанию, поэтому я создал JSFiddle там, где и где Angular предотвращает по умолчанию.

JSFiddle использует директиву Angular, поэтому она должна быть ТОЧНО одинаковой. Вы можете увидеть исходный код здесь: исходный код тега

Надеюсь, это поможет прояснить некоторые.

Мне бы хотелось опубликовать документ до ngHref, но я не могу из-за своей репутации.

Ответ 15

Это то, что я всегда делаю. Работает как шарм!

<a href ng-click="do()">Click</a>

Ответ 16

Самый безопасный способ избежать событий на href - определить его как

<a href="javascript:void(0)" ....>

Ответ 17

Или, если вам нужна встроенная строка, вы можете сделать это:

<a href="#" ng-click="show = !show; $event.preventDefault()">Click to show</a>

Ответ 18

Мне нужно наличие значения атрибута href для деградации (когда js отключен), поэтому я не могу использовать пустой атрибут href (или "#" ), но код выше не работал у меня, потому что мне нужно переменная события (e). Я создал свою собственную директиву:

angular.module('MyApp').directive('clickPrevent', function() {
  return function(scope, element, attrs) {
    return element.on('click', function(e) {
      return e.preventDefault();
    });
  };
});

В HTML:

<a data-click-prevent="true" href="/users/sign_up" ng-click="openSignUpModal()">Sign up</a>

Ответ 19

Заимствование из ответа на теннис. Мне нравится, что вам не нужно создавать настраиваемую директиву для добавления во все ссылки. Однако я не мог заставить его работать в IE8. Вот что, наконец, сработало для меня (используя angular 1.0.6).

Обратите внимание, что 'bind' позволяет использовать jqLite, предоставляемый angular, поэтому нет необходимости обертывать полным jQuery. Также требуется метод stopPropogation.

.directive('a', [
    function() {
        return {
            restrict: 'E',
            link: function(scope, elem, attrs) {

                elem.bind('click', function(e){
                    if (attrs.ngClick || attrs.href === '' || attrs.href == '#'){
                        e.preventDefault();
                        e.stopPropagation();
                    }
                })
            }
        };
    }
])

Ответ 20

Я столкнулся с этой проблемой при использовании якорей для бутстрапа angular. Единственное решение, которое я нашел, чтобы избежать нежелательных побочных эффектов (т.е. Падение вниз, не закрывающееся из-за использования preventDefault()), состояло в следующем:

 <a href="javascript:;" ng-click="do()">Click</a>

Ответ 21

если вы никогда не хотите идти в href... вы должны изменить свою разметку и использовать кнопку, а не тег привязки, потому что семантически это не привязка или ссылка. И наоборот, если у вас есть кнопка, которая выполняет некоторые проверки, а затем перенаправляет ее, это должен быть тег link/anchor, а не кнопка... для целей SEO, а также тестирование [вставить тестовый набор здесь].

для ссылок, которые вы только хотите перенаправить условно, как запрос на сохранение изменений или подтверждение грязного состояния... вы должны использовать ng-click = "someFunction ($ event)" и в someFunction на вашем validationError preventDefault и /stopPropagation.

также только потому, что вы можете не означать, что вы должны. javascript: void (0) хорошо зарекомендовал себя в день... но из-за гнусных хакеров/взломанных браузеров флаги приложений/сайтов, которые используют javascript внутри href... не видят причин для утиного типа выше.

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

Ответ 22

Многие ответы кажутся излишними. Для меня это работает

 <a ng-href="#" ng-click="$event.preventDefault();vm.questionContainer($index)">{{question.Verbiage}}</a>

Ответ 23

/* NG CLICK PREVENT DEFAULT */

app.directive('ngClick', function () {
    return {
        link: function (scope, element, attributes) {
            element.click(function (event) {
                event.preventDefault();
                event.stopPropagation();
            });
        }
    };
});

Ответ 24

Что вы должны сделать, полностью опускает атрибут href.

Если вы посмотрите на исходный код для директивы элемента a (которая является частью ядра Angular), это состояния в строке 29-31:

if (!element.attr(href)) {
    event.preventDefault();
}

Это означает, что Angular уже решает проблему ссылок без href. Единственная проблема, с которой вы все еще сталкиваетесь, - проблема css. Вы все равно можете применить стиль указателя к якорям, у которых есть ng-клики, например:

a[ng-click] {
    /* Styles for anchors without href but WITH ng-click */
    cursor: pointer;
}

Таким образом, вы даже можете сделать свой сайт более доступным, отметив реальные ссылки с тонким, другим стилем, а затем ссылками, которые выполняют функции.

Счастливое кодирование!

Ответ 25

Вы можете отключить перенаправление URL-адресов внутри $location Html5Mode для достижения цели. Вы можете определить его внутри конкретного контроллера, используемого для страницы. Что-то вроде этого:

app.config(['$locationProvider', function ($locationProvider) {
    $locationProvider.html5Mode({
        enabled: true,
        rewriteLinks: false,
        requireBase: false
    });
}]);

Ответ 26

Альтернативой может быть:

<span ng-click="do()">Click</span>