Скажімо, у мене є якорний тег типу
<a href="#" ng-click="do()">Click</a>
Як я можу запобігти переходу браузера до # в AngularJS ?
href=''
щоб використовувати поведінку вказівника миші.
Скажімо, у мене є якорний тег типу
<a href="#" ng-click="do()">Click</a>
Як я можу запобігти переходу браузера до # в AngularJS ?
href=''
щоб використовувати поведінку вказівника миші.
Відповіді:
ОНОВЛЕННЯ : З того часу я передумав це рішення. Після більшого розвитку та витраченого часу на роботу, я вважаю, що кращим рішенням цієї проблеми є наступне:
<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.
href
атрибута має різну поведінку в різних браузерах. Хоча я погоджуюся, що це на сьогоднішній день найчистіше та найефективніше рішення, але у нього є проблеми з перехресними браузерами. Використання директивного підходу дозволяє браузеру обробляти <a>
теги так, як зазвичай, але все ж отримувати ОП відповідь, яку вони шукали.
Згідно з документами для ngHref, ви повинні мати можливість залишити href або виконувати 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 />
Ви можете передати об’єкт $ події своєму методу та зателефонувати $event.preventDefault()
за ним, щоб обробка за замовчуванням не відбулася:
<a href="#" ng-click="do($event)">Click</a>
// then in your controller.do($event) method
$event.preventDefault()
$event.preventDefault()
... IE податку.
ng-click="do(); $event.preventDefault()
наприклад ... хоча, це не обов'язково, оскільки відповідь @ Кріса нижче - правильна. Це може допомогти людям у ситуаціях, коли вони вклали ngClicks і хочуть зателефонувати $event.stopPropagation()
.
Я вважаю за краще використовувати директиви для подібних речей. Ось приклад
<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
об'єктError: $ is not defined
. Що я пропускаю?
angular.element(element).bind('click', function(event){...});
. Це спрацювало. Посилання: jQLite
Хоча Рено дав чудове рішення
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
Я особисто знайшов, що вам також потрібно $ event.stopPropagation (), щоб уникнути деяких побічних ефектів
<a href="#" ng-click="do(); $event.preventDefault(); $event.stopPropagation();">
Click</a>
буде моїм рішенням
ng-click="$event.preventDefault()"
Найпростіше рішення, яке я знайшов, це:
<a href="#" ng-click="do(); $event.preventDefault()">Click</a>
Отже, читаючи ці відповіді, @Chris все ще має найбільш "правильну" відповідь, я думаю, але у нього є одна проблема, вона не показує "покажчик" ....
Тож ось два способи вирішити цю проблему без необхідності додавати курсор: pointer style:
Використовуйте 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" у тому посиланні, яке лякає нещодавно, і не обов'язково безпосередньо стосується кутового додатка.
javascript:;
HTML
тут чистий angularjs: поруч із функцією ng-click можна записати функцію prevenDefault (), відокремлюючи крапку з комою
<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()
}
Оскільки ви створюєте веб-додаток, навіщо вам потрібні посилання?
Поміняйте якіри на кнопки!
<button ng-click="do()"></button>
Найбезпечнішим способом уникнути подій на href було б визначити його як
<a href="javascript:void(0)" ....>
Я б пішов з:
<a ng-click="do()">Click</a>
Ціле це запобігання за замовчуванням мене бентежить, тому я створив там JSFiddle, що ілюструє, коли і де Angular заважає дефолту .
JSFiddle використовує директиву Angular - тому воно повинно бути ТОЧНО таким же. Ви можете побачити вихідний код тут: вихідний код тегу
Я сподіваюся, що це допоможе роз'ясненню для деяких.
Я хотів би опублікувати документа на ngHref, але не можу через свою репутацію.
Дуже багато відповідей здається непосильним. ДЛЯ МНЕ це працює
<a ng-href="#" ng-click="$event.preventDefault();vm.questionContainer($index)">{{question.Verbiage}}</a>
Мені потрібна наявність атрибута href для деградації (коли js вимкнено), тому я не можу використовувати порожній атрибут href (або "#"), але наведений вище код не працював для мене, тому що мені потрібна подія ( д) змінна. Я створив власну директиву:
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>
Запозичення у відповіді тенісгента. Мені подобається, що вам не потрібно створювати власну директиву, щоб додавати всі посилання. Однак я не зміг заставити його працювати в IE8. Ось що, нарешті, працювало для мене (використовуючи кутовий 1.0.6).
Зверніть увагу, що "bind" дозволяє використовувати jqLite, наданий кутовим, тому не потрібно завершувати повний 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();
}
})
}
};
}
])
dropdown
, я хочу розповсюдження, але не поведінку за замовчуванням. Цей фрагмент НЕ рекомендується.
Я зіткнувся з цим самим питанням, коли використовував анкери для кутового завантажувального падіння вниз. Єдине рішення, яке я знайшов, щоб уникнути небажаних побічних ефектів (тобто падіння, яке не закривалося через використання prevenDefault ()), було використання наступного:
<a href="javascript:;" ng-click="do()">Click</a>
якщо ви ніколи не хочете переходити до href ... слід змінити розмітку і використовувати кнопку не тег прив’язки, оскільки семантично це не якір чи посилання. І навпаки, якщо у вас є кнопка, яка робить деякі перевірки, а потім переспрямовує, це має бути тег посилання / прив’язки, а не кнопка ... для цілей SEO, а також тестування [сюди вставити тестовий набір].
для посилань, які ви хочете лише переадресувати лише умовно, як, наприклад, запит на збереження змін або підтвердження брудного стану ... ви повинні використовувати ng-click = "someFunction ($ подія)", а в деякихFunction на вашій валідаціїError prevenDefault та або stopPropagation.
також тільки тому, що ви не можете означати, що слід . javascript: void (0) добре спрацював у той час ... але через жахливі хакери / зломщики браузерів прапор програм / сайтів, які використовують javascript в рамках href ... не бачити причин для того, щоб ducktype був вище.
це 2016 рік з 2010 року. Ніде не майте причин використовувати посилання, які діють як кнопки ... якщо вам все-таки потрібно підтримувати IE8 і нижче, вам потрібно переоцінити своє місце роботи.
/* NG CLICK PREVENT DEFAULT */
app.directive('ngClick', function () {
return {
link: function (scope, element, attributes) {
element.click(function (event) {
event.preventDefault();
event.stopPropagation();
});
}
};
});
Що ви повинні зробити, це href
повністю опустити атрибут.
Якщо ви подивитеся на вихідний кодa
директиви щодо елемента (який є частиною кутового ядра), у рядку 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;
}
Таким чином, ви навіть можете зробити свій сайт більш доступним, позначивши реальні посилання тонкими, різними стилями, а потім посиланнями, що виконують функції.
Щасливого кодування!
Ви можете відключити переадресацію URL-адреси всередині Html5Mode $ location для досягнення мети. Ви можете визначити його всередині певного контролера, який використовується для сторінки. Щось на зразок цього:
app.config(['$locationProvider', function ($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
rewriteLinks: false,
requireBase: false
});
}]);
Якщо ви використовуєте Angular 8 або більше, ви можете створити директиву:
import { Directive, HostListener } from '@angular/core';
@Directive({
selector: '[preventDefault]'
})
export class PreventDefaultDirective {
@HostListener("click", ["$event"])
public onClick(event: any): void
{
console.log('click');
debugger;
event.preventDefault();
}
}
У своєму тезі прив’язки до компонента ви можете його провести так:
<a ngbDropdownToggle preventDefault class="nav-link dropdown-toggle" href="#" aria-expanded="false" aria-haspopup="true" id="nav-dropdown-2">Pages</a>
Модуль додатка повинен мати свою декларацію:
import { PreventDefaultDirective } from './shared/directives/preventdefault.directive';
@NgModule({
declarations: [
AppComponent,
PreventDefaultDirective
Альтернативою може бути:
<span ng-click="do()">Click</span>
span
цілями для клацання. Просто перейдіть до відповіді @ тенісгента - якоря без href
визначеного.
href
.