วิธีการป้องกันเริ่มต้นที่จุดยึดแท็ก?


342

สมมติว่าฉันมีแท็กสมอเช่น

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

ฉันจะป้องกันไม่ให้เบราว์เซอร์นำทางไปยัง # ในAngularJS ได้อย่างไร


14
hrefเช่นเดียวกับคริสกล่าวว่าด้านล่างเพียงแค่ปล่อยออกมา
เจสซี

13
นั่นไม่ใช่สิ่งที่ Chris พูด Jesse ใช้href=''เพื่อรักษาพฤติกรรมการใช้ตัวชี้ของเมาส์
oma

1
คุณเพิ่งลบ # sign จาก href มันก็โอเค
HENG Vongkol

4
หรือเพียงแค่ใช้ href = "javascript: void (0);" เพื่อให้ตัวชี้ แต่ไม่มีการดำเนินการ (จนกว่าคุณจะเพิ่มตัวจัดการคลิกอื่น)
Robba

1
คุณช่วยเปลี่ยนคำตอบที่ดีที่สุดและได้รับการโหวตมากที่สุดโดย Chris - stackoverflow.com/a/11672909 ได้ไหม
Piotr Dobrogost

คำตอบ:


259

อัปเดต : ตั้งแต่ฉันเปลี่ยนใจในโซลูชันนี้ หลังจากการพัฒนาและการใช้เวลามากขึ้นในการทำสิ่งนี้ฉันเชื่อว่าทางออกที่ดีกว่าสำหรับปัญหานี้ก็คือ

<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
ขอบคุณ @matejkramny คำวิจารณ์ที่สร้างสรรค์มาก ข้อเสนอแนะใดที่จะทำให้ "ยุ่ง" น้อยลง?
Tennisgent

1
ตามที่ระบุไว้ในคำตอบอื่น ๆ การมีhrefแอตทริบิวต์ว่างเปล่ามีพฤติกรรมที่แตกต่างกันในเบราว์เซอร์ที่แตกต่างกัน แม้ว่าฉันจะเห็นด้วยว่ามันเป็นทางออกที่สะอาดและมีประสิทธิภาพมากที่สุด แต่ก็มีปัญหาข้ามเบราว์เซอร์ การใช้แนวทาง directive ทำให้เบราว์เซอร์สามารถจัดการ<a>แท็กได้ตามปกติ แต่ยังคงได้รับคำตอบจาก OP ที่พวกเขาต้องการ
Tennisgent

2
งานนี้และทั้งหมด แต่ overkill อย่างจริงจังสำหรับปัญหาที่ง่ายมาก Angular ให้คุณเข้าถึงวัตถุเหตุการณ์ด้วย $ event ดังนั้นคุณสามารถทำสิ่งที่คุณจะทำในเหตุการณ์ js หรือ jquery click อย่างชัดเจน ดูคำตอบนี้stackoverflow.com/a/19240232/1826354และความคิดเห็นของฉันที่มีต่อมัน
Charlie Martin

1
อ๋อ คุณสามารถ. มีคำตอบอีกสองข้อในโพสต์นี้ที่ทำสิ่งที่คุณอธิบายไปแล้ว และฉันเห็นด้วยก็เกินความจริง นั่นเป็นเหตุผลที่ฉันทำการอัปเดตที่ฉันทำ
tennisgent

6
นี่เป็นเรื่องปกติถ้าคุณไม่สนใจการเข้าถึงเว็บไซต์ของคุณ การปล่อย href ออกไปจะไม่สามารถใช้แป้นพิมพ์เพื่อแท็บไปยังรายการนั้นได้ ถ้าคุณไม่เพิ่ม tabindex ด้วยสิ่งที่อยู่ในใจทำไมไม่เพียง แต่ใช้ PreventDefault ... นั่นคือสิ่งที่มันมีอยู่
duhseekoh

319

ตามเอกสารสำหรับ 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 />

6
มันเป็นคำตอบที่ดีจริงๆเท่านั้น อะไรก็ตามที่ต้องมีการสัมผัส DOM หรือเหตุการณ์ในท้องถิ่นนั้นเป็นสิ่งที่น่าสงสัย
วินซ์

4
นี่คือคำตอบที่ถูกต้อง หากคุณดรอป href จากแอตทริบิวต์ <a> AngularJS จะเรียกการป้องกันเริ่มต้น:
pkozlowski.opensource

25
ข้อเสียเพียงอย่างเดียวของการละทิ้งคุณลักษณะ href คือคุณสูญเสียเคอร์เซอร์ 'ตัวชี้' ปกติเมื่อวางเมาส์เหนือลิงก์ คุณสามารถแก้ไขได้โดยเพิ่มกฎให้กับสไตล์ชีตของคุณ: a: hover {cursor: pointer; }
karlgold

35
โปรดทราบว่าสิ่งนี้ทำให้แท็กไม่สามารถแท็บได้ซึ่งไม่สามารถเข้าถึงได้ง่าย
Richard Szalay

3
สำหรับฉันแล้วเบราว์เซอร์ยังคงฟองการคลิก: /
Matej

238

คุณสามารถส่งวัตถุ $ event ไปยังวิธีการของคุณและเรียก$event.preventDefault()ใช้เพื่อให้การประมวลผลเริ่มต้นจะไม่เกิดขึ้น:

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

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

13
ใช่และคุณยังสามารถโทร $ event.stopPropagation () เพื่อให้เหตุการณ์ไม่เกิดฟองสบู่ (โดยทั่วไปคุณสามารถเข้าถึงวัตถุเหตุการณ์ตามที่กำหนดโดย W3C: w3.org/TR/DOM-Level-2- กิจกรรม / events.html # เหตุการณ์ - กิจกรรม )
mna

1
โปรดทราบว่าในขณะที่เขียนนี้การปล่อยให้ href ว่างเปล่า (หรือขาดหายไป) ไม่ทำงานบน IE8 / 9 และ Opera นี่เป็นปีที่แล้วและฉันไม่ได้มีโอกาสลองอีกครั้ง (ฉันเปิดปัญหาย้อนกลับไปที่ Github แต่ฉันคิดว่าพวกเขารีเซ็ตปัญหาในช่วงเวลาที่ผ่านมา) หากสิ่งนี้ได้รับการแก้ไข (หรือคุณไม่สนใจเบราว์เซอร์เหล่านี้) ถ้าอย่างนั้นก็ให้ใช้คำตอบของ Chris! หากใครบางคนสามารถลองและแสดงความคิดเห็น / แก้ไขคำตอบได้ดียิ่งขึ้น
mna

1
@PuerkitoBio - ฉันสามารถยืนยันได้ว่า IE8 และด้านล่างยังคงต้องการ$event.preventDefault()... ภาษี IE
Scotty.NET

4
การส่งเหตุการณ์ $ ไปยังคอนโทรลเลอร์หมายถึงการอ้างอิง DOM ในคอนโทรลเลอร์ของคุณซึ่งหมายความว่าคุณได้เชื่อมโยงมุมมองและคอนโทรลเลอร์ของคุณเข้าด้วยกันแล้ว คุณสามารถเรียกวิธี $ event โดยตรงในนิพจน์ที่ถูกประเมินของคุณng-click="do(); $event.preventDefault()ตัวอย่างเช่น ... ถึงแม้ว่าจะไม่จำเป็นเพราะ @ Chris คำตอบด้านล่างเป็นวิธีที่ถูกต้อง นี้อาจช่วยให้ผู้คนในสถานการณ์ที่พวกเขามี ngClicks ซ้อนกันและพวกเขาต้องการที่จะเรียก$event.stopPropagation()อย่างไร
เบ็นเลช

2
ในที่สุดโซลูชันที่เป็นมิตรกับ SEO คุณอาจต้องการอัปเดต URL เบราว์เซอร์โดยไม่ต้องโหลด ng-view - joelsaupe.com/programming/ วิธีที่คุณมีลิงก์ที่ไม่ได้โหลดมุมมองใหม่ แต่สามารถเปิดในแท็บใหม่และเครื่องมือค้นหาสามารถติดตามพวกเขาได้ เย้!
Tom

111

ฉันชอบที่จะใช้คำสั่งสำหรับสิ่งนี้ นี่คือตัวอย่าง

<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()'อัตโนมัติ

ประโยชน์ที่ได้รับ:

  1. คุณไม่ต้องส่ง$eventวัตถุที่น่าเกลียดเข้ามาในdo()ฟังก์ชันของคุณ
  2. คอนโทรลเลอร์ของคุณสามารถทดสอบได้มากกว่าหน่วยเพราะไม่จำเป็นต้องทำให้$eventวัตถุไม่สมบูรณ์

1
@ Kato Angular มาพร้อมกับชุดย่อยของ jQuery เพื่อทำให้ชีวิตของเราง่ายขึ้น
Neil

3
สิทธิประโยชน์เพิ่มเติม - สามารถใช้งานได้ในIE8และต่ำกว่าหากคุณมีความสำคัญ
Scotty.NET

1
Error: $ is not definedฉันได้รับ ฉันพลาดอะไรไป
Bilal Mirza

7
ฉันพยายามangular.element(element).bind('click', function(event){...});แล้ว มันได้ผล Ref: jQLite
Bilal Mirza

3
แนะนำสั่งหาสิ่งที่ง่ายเช่นนั้นดูเหมือนว่าบิตป่องถ้าคุณถามฉัน ... ตรวจสอบคำตอบของเขาคริสด้านล่าง
เหี่ยว

54

แม้ว่า Renaud จะให้ทางออกที่ดี

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

ฉันเองพบว่าคุณต้องการ $ event.stopPropagation () ในบางกรณีเพื่อหลีกเลี่ยงผลข้างเคียงบางอย่าง

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

จะเป็นทางออกของฉัน


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

13
นี่คือทางออกที่ดีที่สุด แน่นอนคุณสามารถส่งวัตถุ $ event ไปยังฟังก์ชันขอบเขตได้เช่นกัน เช่นเดียวกับ ng-click = "myFunction ($ event, otherParams) จากนั้น $ event.preventDefault () ใน myFunction กลิ้งคำสั่งของคุณเองสำหรับสิ่งนี้คือ overkill
Charlie Martin

34

ทางออกที่ง่ายที่สุดที่ฉันพบคือหนึ่งในนี้:

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

สิ่งนี้ไม่เพียง แต่เป็นวิธีที่ง่ายที่สุด แต่ยังไม่ได้เชื่อมโยงเหตุการณ์กับคอนโทรลเลอร์อย่างที่แนะนำในโซลูชันอื่น ๆ การมีเพศสัมพันธ์กับเหตุการณ์เป็นสิ่งที่คุณควรหลีกเลี่ยงค่าใช้จ่ายเนื่องจากมันทำให้การทดสอบยากขึ้นมาก
jornare

11

ดังนั้นเมื่ออ่านคำตอบเหล่านี้ @Chris ยังคงมีคำตอบที่ "ถูกต้องที่สุด" ฉันคิดว่า แต่มันมีปัญหาหนึ่งข้อไม่แสดง "ตัวชี้" ....

ดังนั้นนี่คือสองวิธีในการแก้ปัญหานี้โดยไม่จำเป็นต้องเพิ่มเคอร์เซอร์: ลักษณะของตัวชี้:

  1. ใช้javascript:void(0)แทน#:

    <a href="javascript:void(0)" ng-click="doSomething()">Do Something</a>
  2. ใช้$event.preventDefault()ในng-clickคำสั่ง (ดังนั้นคุณจะไม่ทำให้ขยะควบคุมกับการอ้างอิงที่เกี่ยวข้องกับ DOM):

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

โดยส่วนตัวฉันชอบอดีตมากกว่าคนหลัง javascript:void(0)มีผลประโยชน์อื่น ๆ ที่ได้รับการกล่าวถึงที่นี่ นอกจากนี้ยังมีการอภิปราย "JavaScript ที่ไม่สร้างความรำคาญ" ในลิงก์ซึ่งน่ากลัวเมื่อเร็ว ๆ นี้และไม่จำเป็นต้องใช้กับแอปพลิเคชันเชิงมุมโดยตรง


2
ทำไม downvote นี้ ฉันยังสังเกตเห็นว่าตัวชี้ไม่แสดงพร้อมคำตอบจากคริส
Wim Deblauwe

2
javascript: void (0) ดีกว่า # ซึ่งสามารถทำหน้าที่ในเส้นทางได้หากคุณกำหนดค่าผิด +1
Shay Elkayam

2
ฉันเพิ่งจะเขียนคำตอบสำหรับเรื่องนี้ คุณสามารถทำได้javascript:;
Adrian

10

คุณสามารถทำได้ดังนี้

1. ลบhrefแอตทริบิวต์จากaแท็กanchor ( )

2.Set เคอร์เซอร์ตัวชี้ใน CSS เพื่อองค์ประกอบคลิกคลิก

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

9

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()
}

7

ลองตัวเลือกที่ฉันเห็นนี้ยังไม่ได้ระบุไว้ข้างต้น:

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

6

เมื่อคุณทำเว็บแอพทำไมคุณถึงต้องการลิงค์?

สลับจุดยึดของคุณเป็นปุ่ม!

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

2
webapps ไม่สามารถยึดได้เมื่อเหรอ?
Robin van Baalen

1
ฉันหมายถึงจุดที่เว็บแอปส่วนใหญ่ไม่ต้องการลิงก์ที่สัมพันธ์กันเช่นเว็บไซต์ทำพวกเขาก็มักจะใช้จุดยึดลิงก์เป็น javascript ทริกเกอร์และไม่เชื่อมโยงไปยังหน้า; ดังนั้นปุ่มที่มีการรีเซ็ตสไตล์เริ่มต้นจะถูกต้องตามความหมายหากไม่มากกว่านั้น
sidonaldson

3
@sidonaldson จริงๆแล้วทุกวันนี้เว็บแอพมากมายขึ้นอยู่กับลิงค์ ดูการกำหนดเส้นทางเชิงมุม
Robert

1
@Robert ใช่ แต่ถ้าคุณใช้เส้นทางในตัวคุณไม่จำเป็นต้องจัดการป้องกันการผิดนัดมันทำเพื่อคุณ ฉันถือว่าตั้งแต่ผู้โพสต์ต้องการยกเลิกลิงค์จุดยึดที่เขาพูดถึงลิงก์ที่ไม่ใช่เส้นทาง ตัวอย่างเช่นการเปิดตัวเป็นกิริยาช่วย ฯลฯ
sidonaldson

2
คำตอบนี้ควรมี upvotes มากขึ้น ในหลายกรณีหากคุณต้องการป้องกันพฤติกรรมการยึดเริ่มต้นคุณใช้จุดยึดเป็นปุ่มไม่ใช่ลิงก์
ItsCosmo

6

หากยังเกี่ยวข้อง:

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

...

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

...

6

วิธีที่ปลอดภัยที่สุดในการหลีกเลี่ยงเหตุการณ์ใน href จะเป็นการกำหนดให้เป็น

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

5

ฉันจะไปกับ:

<a ng-click="do()">Click</a>
  • เพราะตามเอกสารคุณควรปล่อย href แล้ว Angular จะจัดการการป้องกันเริ่มต้นสำหรับคุณ!

ทั้งหมดนี้ป้องกันไม่ให้สิ่งเริ่มต้นได้รับความสับสนกับฉันดังนั้น ฉันได้สร้างJSFiddleมีแสดงให้เห็นถึงเมื่อไหร่และที่ไหนเชิงมุมจะป้องกันไม่ให้ค่าเริ่มต้น

JSFiddle ใช้คำสั่งของ Angular - ดังนั้นจึงควรเหมือนกันทุกประการ คุณสามารถดูซอร์สโค้ดได้ที่นี่: ซอร์สโค้ดของแท็ก

ฉันหวังว่านี่จะช่วยชี้แจงสำหรับบางคน

ฉันชอบโพสต์เอกสารไปยัง ngHref แต่ฉันทำไม่ได้เพราะชื่อเสียงของฉัน



4

หรือถ้าคุณต้องการแบบอินไลน์คุณสามารถทำได้:

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

4

ดูเหมือนคำตอบมากเกินไป สำหรับฉันงานนี้

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

2

ฉันต้องการสถานะของแอตทริบิวต์ 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>

2

ยืมมาจากคำตอบของนักเทนนิส ฉันชอบที่คุณไม่ต้องสร้างคำสั่งที่กำหนดเองเพื่อเพิ่มในลิงก์ทั้งหมด อย่างไรก็ตามฉันไม่สามารถให้เขาทำงานใน 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();
                    }
                })
            }
        };
    }
])

3
นี้ฆ่าไปมาก ตัวอย่างเช่นเมื่อฉันใช้ Twitter Bootstrap dropdownฉันต้องการเผยแพร่ แต่ไม่ใช่พฤติกรรมเริ่มต้น ตัวอย่างข้อมูลนี้จะไม่แนะนำ
Robin van Baalen

2

ฉันพบปัญหาเดียวกันนี้เมื่อใช้จุดยึดสำหรับ bootstrap แบบเลื่อนลง ทางออกเดียวที่ฉันพบว่าหลีกเลี่ยงผลข้างเคียงที่ไม่พึงประสงค์ (เช่นเลื่อนลงไม่ปิดเนื่องจากการใช้ preventDefault ()) คือการใช้สิ่งต่อไปนี้:

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

2

หากคุณไม่ต้องการไปที่ href ... คุณควรเปลี่ยนมาร์กอัปและใช้ปุ่มที่ไม่ใช่แท็กจุดยึดเนื่องจากความหมายไม่ใช่จุดยึดหรือลิงก์ ตรงกันข้ามถ้าคุณมีปุ่มที่ตรวจสอบบางอย่างแล้วเปลี่ยนเส้นทางมันควรจะเป็น link / anchor tag และไม่ใช่ปุ่ม ... สำหรับการทำ SEO และการทดสอบ [insert ชุดทดสอบที่นี่]

สำหรับลิงก์ที่คุณต้องการเปลี่ยนเส้นทางอย่างมีเงื่อนไขเช่นพร้อมต์เพื่อบันทึกการเปลี่ยนแปลงหรือรับทราบสถานะสกปรก ... คุณควรใช้ ng-click = "someFunction ($ event)" และใน someFunction ใน validationError ป้องกันDefaultและหรือ stopPropagation ของคุณ

นอกจากนี้ยังเป็นเพียงแค่เพราะคุณสามารถไม่ได้หมายความว่าคุณควร javascript: void (0) ทำงานได้ดีในวันนี้ ... แต่เนื่องจากแฮกเกอร์ / แคร็กเกอร์ที่ชั่วร้ายเบราว์เซอร์ตั้งค่าสถานะแอป / ไซต์ที่ใช้งานจาวาสคริปต์ภายใน href ... ดูเหตุผลที่เป็ดชนิดด้านบนไม่มี ..

มันเป็นปีพ. ศ. 2553 เนื่องจากไม่มีเหตุผลที่จะใช้ลิงก์ที่ทำหน้าที่เหมือนปุ่ม ... หากคุณยังต้องรองรับ IE8 และต่ำกว่าคุณต้องประเมินสถานที่ธุรกิจของคุณใหม่


1
/* NG CLICK PREVENT DEFAULT */

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

1

สิ่งที่คุณควรทำคือละเว้นแอ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;
}

ดังนั้นคุณสามารถทำให้เว็บไซต์ของคุณสามารถเข้าถึงได้มากขึ้นด้วยการทำเครื่องหมายลิงก์จริงด้วยสไตล์ที่ละเอียดและแตกต่างจากนั้นลิงก์ที่ใช้งานฟังก์ชั่น

การเข้ารหัสที่มีความสุข!


1

คุณสามารถปิดการเปลี่ยนเส้นทาง url ใน Html5Mode ของ $ location เพื่อให้บรรลุวัตถุประสงค์ คุณสามารถกำหนดไว้ในตัวควบคุมเฉพาะที่ใช้สำหรับหน้า บางสิ่งเช่นนี้

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


1

หากคุณใช้ 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

-1

ทางเลือกอาจเป็น:

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

1
มันเป็นการปฏิบัติที่น่ากลัวในการใช้spanเพื่อวัตถุประสงค์ในการคลิกที่ไม่เหมาะสม เพียงไปที่คำตอบของ @ tennisgent - จุดยึดโดยไม่ต้องhrefกำหนด
Robin van Baalen

1
@RobinvanBaalen องค์ประกอบการขยายได้รับการกำหนดให้เป็นแบบคลิกได้ตั้งแต่อย่างน้อย HTML 4.0.1: w3.org/TR/html401/struct/global.html#edef-SPAN w3.org/TR/html5/dom.html#global-attributes html.spec.whatwg.org/multipage/dom.html#global-attributes
Terence Bandoian

1
หากคุณ <span> สวัสดี </span> ตั้งแต่นั้นคลิกได้เมื่อไหร่ สิ่งที่สเป็คอาจกล่าวได้คือ <span> สามารถใช้ภายในองค์ประกอบที่คลิกได้เช่น <a> หรือ <button> แต่จากนั้นอีกครั้งองค์ประกอบบล็อกแบบอินไลน์ทั้งหมด (img, span, ฯลฯ ) สามารถสร้างให้คลิกได้ด้วยวิธีนั้น การขยายตัวนั้นไม่สามารถคลิกได้
Robin van Baalen

1
@RobinvanBaalen โปรดดูลิงก์ด้านบน แอตทริบิวต์ onclick สำหรับองค์ประกอบขยายได้รับการกำหนดตั้งแต่อย่างน้อย HTML 4.01
Terence Bandoian

1
ฉันไม่เคยพูดว่าการเพิ่มตัวจัดการเหตุการณ์จะไม่ทำงานเป็นระยะ ฉันบอกว่ามันเป็นวิธีปฏิบัติที่ไม่ดีในการสร้างองค์ประกอบที่ไม่สามารถคลิกได้เช่นช่วง, div, ส่วน, ul, li และอื่น ๆ คลิกได้โดยใช้ตัวจัดการเหตุการณ์จาวาสคริปต์ มันคือทั้งหมดที่เกี่ยวกับความหมาย ซีแมนทิกส์ใน HTML เป็นการฝึกให้เนื้อหาในความหมายและโครงสร้างของหน้าโดยใช้องค์ประกอบที่เหมาะสม
Robin van Baalen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.