สมมติว่าฉันมีแท็กสมอเช่น
<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
แอตทริบิวต์ว่างเปล่ามีพฤติกรรมที่แตกต่างกันในเบราว์เซอร์ที่แตกต่างกัน แม้ว่าฉันจะเห็นด้วยว่ามันเป็นทางออกที่สะอาดและมีประสิทธิภาพมากที่สุด แต่ก็มีปัญหาข้ามเบราว์เซอร์ การใช้แนวทาง directive ทำให้เบราว์เซอร์สามารถจัดการ<a>
แท็กได้ตามปกติ แต่ยังคงได้รับคำตอบจาก OP ที่พวกเขาต้องการ
ตามเอกสารสำหรับ 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 ไปยังวิธีการของคุณและเรียก$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()
ตัวอย่างเช่น ... ถึงแม้ว่าจะไม่จำเป็นเพราะ @ Chris คำตอบด้านล่างเป็นวิธีที่ถูกต้อง นี้อาจช่วยให้ผู้คนในสถานการณ์ที่พวกเขามี 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){...});
แล้ว มันได้ผล Ref: jQLite
แม้ว่า Renaud จะให้ทางออกที่ดี
<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 ยังคงมีคำตอบที่ "ถูกต้องที่สุด" ฉันคิดว่า แต่มันมีปัญหาหนึ่งข้อไม่แสดง "ตัวชี้" ....
ดังนั้นนี่คือสองวิธีในการแก้ปัญหานี้โดยไม่จำเป็นต้องเพิ่มเคอร์เซอร์: ลักษณะของตัวชี้:
ใช้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:;
คุณสามารถทำได้ดังนี้
1. ลบhref
แอตทริบิวต์จากa
แท็กanchor ( )
2.Set เคอร์เซอร์ตัวชี้ใน CSS เพื่อองค์ประกอบคลิกคลิก
[ng-click],
[data-ng-click],
[x-ng-click] {
cursor: pointer;
}
HTML
ที่นี่เชิงมุมบริสุทธิ์: ใกล้กับฟังก์ชั่น 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()
}
ลองตัวเลือกที่ฉันเห็นนี้ยังไม่ได้ระบุไว้ข้างต้น:
<a href="" ng-click="do()">Click</a>
เมื่อคุณทำเว็บแอพทำไมคุณถึงต้องการลิงค์?
สลับจุดยึดของคุณเป็นปุ่ม!
<button ng-click="do()"></button>
หากยังเกี่ยวข้อง:
<a ng-click="unselect($event)" />
...
scope.unselect = function( event ) {
event.preventDefault();
event.stopPropagation();
}
...
วิธีที่ปลอดภัยที่สุดในการหลีกเลี่ยงเหตุการณ์ใน href จะเป็นการกำหนดให้เป็น
<a href="javascript:void(0)" ....>
ฉันจะไปกับ:
<a ng-click="do()">Click</a>
ทั้งหมดนี้ป้องกันไม่ให้สิ่งเริ่มต้นได้รับความสับสนกับฉันดังนั้น ฉันได้สร้างJSFiddleมีแสดงให้เห็นถึงเมื่อไหร่และที่ไหนเชิงมุมจะป้องกันไม่ให้ค่าเริ่มต้น
JSFiddle ใช้คำสั่งของ Angular - ดังนั้นจึงควรเหมือนกันทุกประการ คุณสามารถดูซอร์สโค้ดได้ที่นี่: ซอร์สโค้ดของแท็ก
ฉันหวังว่านี่จะช่วยชี้แจงสำหรับบางคน
ฉันชอบโพสต์เอกสารไปยัง ngHref แต่ฉันทำไม่ได้เพราะชื่อเสียงของฉัน
นี่คือสิ่งที่ฉันทำอยู่เสมอ ทำงานเหมือนจับใจ!
<a href ng-click="do()">Click</a>
หรือถ้าคุณต้องการแบบอินไลน์คุณสามารถทำได้:
<a href="#" ng-click="show = !show; $event.preventDefault()">Click to show</a>
ดูเหมือนคำตอบมากเกินไป สำหรับฉันงานนี้
<a ng-href="#" ng-click="$event.preventDefault();vm.questionContainer($index)">{{question.Verbiage}}</a>
ฉันต้องการสถานะของแอตทริบิวต์ 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>
ยืมมาจากคำตอบของนักเทนนิส ฉันชอบที่คุณไม่ต้องสร้างคำสั่งที่กำหนดเองเพื่อเพิ่มในลิงก์ทั้งหมด อย่างไรก็ตามฉันไม่สามารถให้เขาทำงานใน IE8 ได้ นี่คือสิ่งที่ใช้งานได้ในที่สุดสำหรับฉัน (ใช้เชิงมุม 1.0.6)
โปรดสังเกตว่า 'การผูก' อนุญาตให้คุณใช้ 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
ฉันต้องการเผยแพร่ แต่ไม่ใช่พฤติกรรมเริ่มต้น ตัวอย่างข้อมูลนี้จะไม่แนะนำ
ฉันพบปัญหาเดียวกันนี้เมื่อใช้จุดยึดสำหรับ bootstrap แบบเลื่อนลง ทางออกเดียวที่ฉันพบว่าหลีกเลี่ยงผลข้างเคียงที่ไม่พึงประสงค์ (เช่นเลื่อนลงไม่ปิดเนื่องจากการใช้ preventDefault ()) คือการใช้สิ่งต่อไปนี้:
<a href="javascript:;" ng-click="do()">Click</a>
หากคุณไม่ต้องการไปที่ href ... คุณควรเปลี่ยนมาร์กอัปและใช้ปุ่มที่ไม่ใช่แท็กจุดยึดเนื่องจากความหมายไม่ใช่จุดยึดหรือลิงก์ ตรงกันข้ามถ้าคุณมีปุ่มที่ตรวจสอบบางอย่างแล้วเปลี่ยนเส้นทางมันควรจะเป็น link / anchor tag และไม่ใช่ปุ่ม ... สำหรับการทำ SEO และการทดสอบ [insert ชุดทดสอบที่นี่]
สำหรับลิงก์ที่คุณต้องการเปลี่ยนเส้นทางอย่างมีเงื่อนไขเช่นพร้อมต์เพื่อบันทึกการเปลี่ยนแปลงหรือรับทราบสถานะสกปรก ... คุณควรใช้ ng-click = "someFunction ($ event)" และใน someFunction ใน validationError ป้องกันDefaultและหรือ stopPropagation ของคุณ
นอกจากนี้ยังเป็นเพียงแค่เพราะคุณสามารถไม่ได้หมายความว่าคุณควร javascript: void (0) ทำงานได้ดีในวันนี้ ... แต่เนื่องจากแฮกเกอร์ / แคร็กเกอร์ที่ชั่วร้ายเบราว์เซอร์ตั้งค่าสถานะแอป / ไซต์ที่ใช้งานจาวาสคริปต์ภายใน href ... ดูเหตุผลที่เป็ดชนิดด้านบนไม่มี ..
มันเป็นปีพ. ศ. 2553 เนื่องจากไม่มีเหตุผลที่จะใช้ลิงก์ที่ทำหน้าที่เหมือนปุ่ม ... หากคุณยังต้องรองรับ 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();
}
ซึ่งหมายความว่าแองกูลาร์กำลังแก้ไขปัญหาการเชื่อมโยงโดยไม่ต้องใช้ 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
เพื่อวัตถุประสงค์ในการคลิกที่ไม่เหมาะสม เพียงไปที่คำตอบของ @ tennisgent - จุดยึดโดยไม่ต้องhref
กำหนด
href
เช่นเดียวกับคริสกล่าวว่าด้านล่างเพียงแค่ปล่อยออกมา