เมื่อฉันมีลิงค์ที่เชื่อมต่อกับเหตุการณ์ jQuery หรือ JavaScript เช่น:
<a href="#">My Link</a>
ฉันจะป้องกันไม่ให้เลื่อนไปด้านบนได้อย่างไร เมื่อฉันลบแอตทริบิวต์ href ออกจากจุดยึดหน้าเว็บจะไม่เลื่อนไปด้านบน แต่ดูเหมือนว่าลิงก์จะไม่สามารถคลิกได้
เมื่อฉันมีลิงค์ที่เชื่อมต่อกับเหตุการณ์ jQuery หรือ JavaScript เช่น:
<a href="#">My Link</a>
ฉันจะป้องกันไม่ให้เลื่อนไปด้านบนได้อย่างไร เมื่อฉันลบแอตทริบิวต์ href ออกจากจุดยึดหน้าเว็บจะไม่เลื่อนไปด้านบน แต่ดูเหมือนว่าลิงก์จะไม่สามารถคลิกได้
คำตอบ:
คุณต้องป้องกันไม่ให้การดำเนินการเริ่มต้นสำหรับเหตุการณ์คลิก (เช่นการนำทางไปยังเป้าหมายลิงก์) ไม่ให้เกิดขึ้น
มีสองวิธีในการทำเช่นนี้
event.preventDefault()
เรียกใช้.preventDefault()
เมธอดของวัตถุเหตุการณ์ที่ส่งผ่านไปยังตัวจัดการของคุณ หากคุณใช้ jQuery เพื่อผูกตัวจัดการของคุณเหตุการณ์นั้นจะเป็นอินสแตนซ์ของjQuery.Event
และจะเป็นเวอร์ชัน jQuery ของ.preventDefault()
. หากคุณกำลังใช้addEventListener
เพื่อผูกตัวจัดการของคุณจะเป็นEvent
เวอร์ชัน DOM และดิบของ.preventDefault()
. ไม่ว่าจะด้วยวิธีใดก็ตามที่คุณต้องการ
ตัวอย่าง:
$('#ma_link').click(function($e) {
$e.preventDefault();
doSomething();
});
document.getElementById('#ma_link').addEventListener('click', function (e) {
e.preventDefault();
doSomething();
})
return false;
การส่งคืนเท็จจากตัวจัดการเหตุการณ์จะเรียก event.stopPropagation () และ event.preventDefault () โดยอัตโนมัติ
ดังนั้นด้วย jQuery คุณสามารถใช้วิธีนี้เพื่อป้องกันพฤติกรรมลิงก์เริ่มต้น:
$('#ma_link').click(function(e) {
doSomething();
return false;
});
หากคุณใช้เหตุการณ์ DOM แบบดิบสิ่งนี้จะใช้ได้กับเบราว์เซอร์สมัยใหม่ด้วยเนื่องจากข้อกำหนด HTML 5 กำหนดพฤติกรรมนี้ อย่างไรก็ตามข้อกำหนดรุ่นเก่าไม่ได้ดังนั้นหากคุณต้องการความเข้ากันได้สูงสุดกับเบราว์เซอร์รุ่นเก่าคุณควรโทรติดต่อ.preventDefault()
อย่างชัดเจน ดูevent.preventDefault () เทียบกับ return false (ไม่มี jQuery)สำหรับรายละเอียดข้อมูลจำเพาะ
คุณสามารถตั้งค่า href ของคุณเป็น#!
แทน#
ตัวอย่างเช่น,
<a href="#!">Link</a>
จะไม่ทำการเลื่อนใด ๆ เมื่อคลิก
ระวัง! การดำเนินการนี้จะยังคงเพิ่มรายการในประวัติของเบราว์เซอร์เมื่อคลิกซึ่งหมายความว่าหลังจากคลิกลิงก์ของคุณปุ่มย้อนกลับของผู้ใช้จะไม่นำพวกเขาไปยังหน้าที่เคยเปิดไว้ ด้วยเหตุนี้จึงควรใช้.preventDefault()
แนวทางนี้หรือใช้ทั้งสองอย่างร่วมกัน
นี่คือ Fiddle ที่แสดงสิ่งนี้ (เพียงแค่ scrunch เบราว์เซอร์ของคุณลงจนกว่าคุณจะได้รับแถบเลื่อน):
http://jsfiddle.net/9dEG7/
ลักษณะการทำงานนี้ระบุไว้ในข้อมูลจำเพาะ HTML5 ภายใต้ส่วนการนำทางไปยังตัวระบุแฟรกเมนต์ สาเหตุที่ลิงก์ที่มี href "#"
เป็นสาเหตุให้เอกสารเลื่อนไปด้านบนคือลักษณะการทำงานนี้ถูกระบุไว้อย่างชัดเจนว่าเป็นวิธีจัดการกับตัวระบุส่วนที่ว่างเปล่า:
2. ถ้า
fragid
เป็นสตริงว่างส่วนที่ระบุของเอกสารจะอยู่ด้านบนสุดของเอกสาร
การใช้ href "#!"
แทนใช้งานได้เพียงเพราะหลีกเลี่ยงกฎนี้ ไม่มีอะไรวิเศษเกี่ยวกับเครื่องหมายอัศเจรีย์ - เพียงแค่สร้างตัวระบุส่วนที่ใช้งานได้สะดวกเนื่องจากแตกต่างอย่างเห็นได้ชัดกับความเปราะบางทั่วไปและไม่น่าจะตรงกับid
หรือname
องค์ประกอบบนหน้าของคุณ อันที่จริงเราสามารถใส่เกือบทุกอย่างหลังการแฮช เศษส่วนเพียงอย่างเดียวที่ไม่เพียงพอคือสตริงว่างคำว่า 'top' หรือสตริงที่ตรงกับname
หรือid
แอตทริบิวต์ขององค์ประกอบบนหน้า
ยิ่งไปกว่านั้นเราแค่ต้องการตัวระบุส่วนที่จะทำให้เราผ่านไปยังขั้นตอนที่ 8 ในอัลกอริทึมต่อไปนี้เพื่อกำหนดส่วนที่ระบุของเอกสารจากส่วนย่อย
ใช้อัลกอริธึมตัวแยกวิเคราะห์ URL กับ URL และปล่อยให้Fragidเป็นส่วนประกอบส่วนย่อยของ URL ที่แยกวิเคราะห์ผลลัพธ์
ถ้า
fragid
เป็นสตริงว่างส่วนที่ระบุของเอกสารจะอยู่ด้านบนสุดของเอกสาร หยุดอัลกอริทึมที่นี่อนุญาตเป็นผลมาจากร้อยละถอดรหัส
fragid bytes
fragid
อนุญาต
decoded fragid
เป็นผลมาจากการใช้ขั้นตอนวิธีการถอดรหัส UTF-8fragid bytes
ไป หากตัวถอดรหัส UTF-8 แสดงข้อผิดพลาดของตัวถอดรหัสให้ยกเลิกตัวถอดรหัสและข้ามไปยังขั้นตอนที่ระบุว่าno decoded fragid
แทนหากมีองค์ประกอบใน DOM ที่มี ID เท่ากับ
decoded fragid
องค์ประกอบแรกดังกล่าวตามลำดับแบบต้นไม้คือส่วนที่ระบุของเอกสาร หยุดอัลกอริทึมที่นี่ไม่มีการถอดรหัส Fragid : หากมีองค์ประกอบใน DOM ที่มีแอตทริบิวต์ name ซึ่งมีค่าเท่ากับ
fragid
( notdecoded fragid
) องค์ประกอบแรกดังกล่าวตามลำดับแบบต้นไม้คือส่วนที่ระบุของเอกสาร หยุดอัลกอริทึมที่นี่หากFragidเป็นการจับคู่ ASCII ที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่สำหรับสตริง
top
ส่วนที่ระบุของเอกสารจะอยู่ด้านบนสุดของเอกสาร หยุดอัลกอริทึมที่นี่มิฉะนั้นจะไม่มีส่วนที่ระบุของเอกสาร
ตราบใดที่เราเข้าสู่ขั้นตอนที่ 8 และไม่มีส่วนที่ระบุของเอกสารกฎต่อไปนี้จะมีผล:
หากไม่มีส่วนที่ระบุ ... ตัวแทนผู้ใช้จะต้องไม่ทำอะไรเลย
ซึ่งเป็นสาเหตุที่ทำให้เบราว์เซอร์ไม่เลื่อน
preventDefault()
ในตัวจัดการการคลิก - ค่อนข้างน่าเศร้า
แนวทางง่ายๆคือการใช้ประโยชน์จากรหัสนี้:
<a href="javascript:void(0);">Link Title</a>
วิธีนี้ไม่ได้บังคับให้รีเฟรชหน้าดังนั้นแถบเลื่อนจึงอยู่ในตำแหน่ง นอกจากนี้ยังช่วยให้คุณสามารถเปลี่ยนเหตุการณ์ onclick โดยทางโปรแกรมและจัดการการผูกเหตุการณ์ฝั่งไคลเอ็นต์โดยใช้ jQuery
ด้วยเหตุผลเหล่านี้วิธีแก้ปัญหาข้างต้นจึงดีกว่า:
<a href="javascript:myClickHandler();">Link Title</a>
<a href="#" onclick="myClickHandler(); return false;">Link Title</a>
โดยที่วิธีสุดท้ายจะหลีกเลี่ยงปัญหาการเลื่อน - กระโดดหากวิธีการ myClickHandler ไม่ล้มเหลว
การส่งคืนเท็จจากรหัสที่คุณเรียกจะใช้งานได้และในหลาย ๆ กรณีเป็นวิธีที่ต้องการ แต่คุณสามารถทำได้เช่นกัน
<a href="javascript:;">Link Title</a>
เมื่อพูดถึง SEO จริงๆแล้วมันขึ้นอยู่กับว่าลิงก์ของคุณจะใช้ทำอะไร หากคุณจะใช้มันเพื่อเชื่อมโยงไปยังเนื้อหาอื่น ๆ จริงฉันก็เห็นด้วยอย่างยิ่งว่าคุณต้องการสิ่งที่มีความหมายที่นี่ แต่ถ้าคุณใช้ลิงก์เพื่อวัตถุประสงค์ในการใช้งานอาจจะเหมือนกับ Stack Overflow สำหรับแถบเครื่องมือโพสต์ (ตัวหนาตัวเอียงไฮเปอร์ลิงก์ ฯลฯ ) ก็คงไม่สำคัญ
คุณควรเปลี่ยนไฟล์
<a href="#">My Link</a>
ถึง
<a href="javascript:;">My Link</a>
วิธีนี้เมื่อคลิกลิงก์หน้าจะไม่เลื่อนขึ้นไปด้านบน วิธีนี้สะอาดกว่าการใช้ href = "#" แล้วป้องกันไม่ให้เหตุการณ์เริ่มต้นทำงาน
ฉันมีเหตุผลที่ดีสำหรับนี้ในคำตอบแรกที่จะคำถามนี้เหมือนreturn false;
จะไม่ดำเนินการถ้าฟังก์ชั่นที่เรียกว่าโยนข้อผิดพลาดหรือคุณอาจจะเพิ่มreturn false;
ไปยังdoSomething()
ฟังก์ชั่นแล้วลืมที่จะใช้return doSomething();
ลองสิ่งนี้:
<a href="#" onclick="return false;">My Link</a>
หากคุณสามารถเปลี่ยนhref
ค่าได้คุณควรใช้:
<a href="javascript:void(0);">Link Title</a>
วิธีแก้ปัญหาที่เป็นระเบียบอีกวิธีหนึ่งที่ฉันเพิ่งสร้างขึ้นคือการใช้ jQuery เพื่อหยุดการคลิกไม่ให้เกิดขึ้นและทำให้หน้าเลื่อน แต่สำหรับhref="#"
ลิงก์เท่านั้น
<script type="text/javascript">
/* Stop page jumping when links are pressed */
$('a[href="#"]').live("click", function(e) {
return false; // prevent default click action from happening!
e.preventDefault(); // same thing as above
});
</script>
return false
ควรอยู่หลังpreventDefault()
เส้นมิฉะนั้นคุณจะไม่ไปถึงบรรทัดที่สองนี้?
นอกจากนี้คุณสามารถใช้event.preventDefaultภายในแอตทริบิวต์onclick
<a href="#" onclick="event.preventDefault(); doSmth();">doSmth</a>
ไม่จำเป็นต้องเขียนเหตุการณ์คลิก exstra
คุณสามารถเขียนแบบนี้ได้เช่นกัน: -
<a href="#!" onclick="function()">Delete User</a>
เมื่อเรียกใช้ฟังก์ชันให้ทำตามreturn false
ตัวอย่าง:
<input type="submit" value="Add" onclick="addNewPayment();return false;">
สร้างเพจที่มีสองลิงค์ - อันหนึ่งที่ด้านบนและอีกอันที่ด้านล่าง เมื่อคลิกลิงก์บนสุดหน้าจะต้องเลื่อนลงไปที่ด้านล่างของหน้าที่มีลิงค์ด้านล่าง เมื่อคลิกลิงก์ด้านล่างหน้าจะต้องเลื่อนขึ้นไปที่ด้านบนของหน้า
<a onclick="yourfunction()">
มันจะทำงานได้ดี ไม่จำเป็นต้องเพิ่ม href = "#"
คุณอาจต้องการตรวจสอบ CSS ของคุณ ในตัวอย่างที่นี่: https://css-tricks.com/the-checkbox-hack/position: absolute; top: -9999px;
มี สิ่งนี้เป็นเรื่องตลกโดยเฉพาะบน Chrome เนื่องจากonclick="whatever"
ยังคงข้ามไปยังตำแหน่งที่แน่นอนขององค์ประกอบที่คลิก
ถอดposition: absolute; top: -9999px;
สำหรับdisplay: none;
อาจช่วย
สำหรับ Bootstrap 3 สำหรับการยุบหากคุณไม่ระบุ data-target บนจุดยึดและพึ่งพา href เพื่อกำหนดเป้าหมายเหตุการณ์จะถูกป้องกัน หากคุณใช้ data-target คุณจะต้องป้องกันเหตุการณ์ด้วยตัวเอง
<button type="button" class="btn btn-default" data-toggle="collapse" data-target="#demo">Collapse This</button>
<div id="demo" class="collapse">
<p>Lorem ipsum dolor sit amet</p>
</div>