ฟังก์ชัน JavaScript ใน href เทียบกับ onclick


474

ฉันต้องการใช้งานฟังก์ชั่น JavaScript ง่ายๆในการคลิกโดยไม่เปลี่ยนเส้นทาง

มีความแตกต่างหรือประโยชน์ใด ๆ ระหว่างการวางสาย JavaScript ในhrefแอตทริบิวต์ (เช่นนี้:

<a href="javascript:my_function();window.print();">....</a>

) เทียบกับวางไว้ในonclickแอตทริบิวต์ (ผูกไว้กับonclickเหตุการณ์) หรือไม่


5
คำถามนี้ถูกกล่าวถึงก่อนหน้านี้: stackoverflow.com/questions/245868/…
SolutionYogi

คำตอบ:


276

การวาง onclick ไว้ใน href จะทำให้ผู้ที่เชื่อมั่นแยกเนื้อหาออกจากพฤติกรรม / การกระทำ เหตุผลก็คือเนื้อหา html ของคุณควรเน้นเฉพาะเนื้อหาไม่ใช่งานนำเสนอหรือพฤติกรรม

เส้นทางทั่วไปในทุกวันนี้คือการใช้ไลบรารี javascript (เช่น jquery) และสร้างตัวจัดการเหตุการณ์โดยใช้ไลบรารีนั้น มันจะมีลักษณะเช่น:

$('a').click( function(e) {e.preventDefault(); /*your_code_here;*/ return false; } );

1
หรือ mootools, ต้นแบบ, dojo ... หรือธรรมดาบน javascript แต่นั่นจะเป็นโค้ดที่มากกว่าทั้งหมด แต่คุ้มค่ากับการออกกำลังกาย
Ryan ฟลอเรนซ์

15
หากคุณไม่ต้องทำอะไรกับวัตถุเหตุการณ์จาวาสคริปต์ธรรมดานั้นค่อนข้างง่าย รับโหนด DOM พร้อมด้วย obj = document.getElementById () จากนั้นตั้งค่า obj.onclick = foo
Matt Bridges

1
สิ่งที่เกี่ยวกับการแยกเนื้อหาเมื่อสร้าง <a href> ในทันทีพูดในหน้าต่างป๊อปอัปและคุณยังต้องการพฤติกรรมการคลิกพิเศษ
Serge

6
แต่คำถามที่ถามเกี่ยวกับความแตกต่างระหว่างการโทรแบบอินไลน์ JS hrefกับแบบอินไลน์onclickไม่ใช่หรือไม่ สมมติว่าคุณกำลังจะใส่มันแบบอินไลน์ด้วยเหตุผลบางอย่างที่คุณควรใช้? (ในทางปฏิบัติฉันจะทำสิ่งที่คุณแนะนำ แต่ดูเหมือนว่าคุณจะข้ามความแตกต่างระหว่างคุณลักษณะทั้งสอง)
nnnnnn

1
ครั้งเดียวที่ฉันจะแนะนำให้วางฟังก์ชั่นการโทรแบบอินไลน์กับการมีเหตุการณ์ onclick สำหรับลิงค์คือถ้าคุณกำลังสร้างลิงค์แบบไดนามิกภายในหน้าเว็บที่ทุกคนจะเรียกฟังก์ชั่นเดียวกัน แต่อาจไม่มีรหัสที่ไม่ซ้ำกัน ฉันมีเว็บฟอร์มที่ผู้ใช้สามารถเพิ่มและลบรายการและฉันวาง onclick ในลิงก์ของ href ใน divs ที่สร้างขึ้นแบบไดนามิกเพื่อให้ฉันสามารถเริ่มต้นการประมวลผลสคริปต์ได้เร็วขึ้นแทนที่จะใช้สิ่งที่เฉพาะเจาะจงน้อยกว่าเช่น id ญาติหรือ ชื่อคลาส
MistyDawn

976

เลว:

<a id="myLink" href="javascript:MyFunction();">link text</a>

ดี:

<a id="myLink" href="#" onclick="MyFunction();">link text</a>

ที่ดีกว่า:

<a id="myLink" href="#" onclick="MyFunction();return false;">link text</a>

ดียิ่งขึ้น 1:

<a id="myLink" title="Click to do something"
 href="#" onclick="MyFunction();return false;">link text</a>

ดียิ่งขึ้น 2:

<a id="myLink" title="Click to do something"
 href="PleaseEnableJavascript.html" onclick="MyFunction();return false;">link text</a>

ทำไมถึงดีกว่า เพราะreturn falseจะป้องกันเบราว์เซอร์ไม่ให้ติดตามลิงก์

ที่ดีที่สุด:

ใช้ jQuery หรือกรอบงานที่คล้ายกันอื่น ๆ เพื่อแนบ onclick handler ตาม ID ขององค์ประกอบ

$('#myLink').click(function(){ MyFunction(); return false; });

21
จะมีวิธีแก้ไขปัญหาอื่นซึ่งจะดีที่สุดที่hrefไม่ได้ตั้งค่าไว้#แต่ไปยังลิงก์จริงสำหรับเบราว์เซอร์ noJS
helly0d

6
จะเป็นอย่างไรถ้าฉันบอกคุณว่าคนแรก (ไม่ดี) คนหนึ่งทำงานแบบเดียวกัน (ขวา) ในเบราว์เซอร์ทุกตัวที่มีมิดคลิก
Vloxxity

14
อะไรคือสิ่งที่ไม่ดีเกี่ยวกับ <a id="myLink" href="javascript:MyFunction() ;">
Vaddadi Kartick

6
เพียง 5 เซนต์ต่ำต้อยของฉัน: "ตัวเลือกที่ดีที่สุด" คือการใช้ปุ่มสำหรับคลิก (เหตุการณ์ onclick?) และปล่อยจุดยึดด้วย href ของสิ่งที่พวกเขาตั้งใจออกแบบดั้งเดิมของพวกเขาในสถานที่แรก: เป็นจุดยึดสำหรับลิงก์ไปยังหน้าอื่น ๆ
nidalpres

4
คลิกผูกพันกับจาวาสคริปต์มีข้อเสียอย่างหนึ่ง: ต่อมาเมื่อคุณแก้ไขข้อบกพร่องในรูปแบบของเขามันยากที่จะหาที่ไหนและจาวาสคริปต์ประเภทใดที่มีผลผูกพันกับองค์ประกอบนั้น
Maarten Kieft

69

ในแง่ของจาวาสคริปต์ความแตกต่างอย่างหนึ่งก็คือthisคำสำคัญในonclickตัวจัดการจะอ้างถึงองค์ประกอบ DOM ที่มีonclickคุณสมบัติเป็น (ในกรณีนี้คือ<a>องค์ประกอบ) ในขณะthisที่hrefแอตทริบิวต์จะอ้างถึงwindowวัตถุ

ในแง่ของการนำเสนอหากhrefแอตทริบิวต์ขาดจากลิงก์ (เช่น<a onclick="[...]">) ตามค่าเริ่มต้นเบราว์เซอร์จะแสดงtextเคอร์เซอร์ (และไม่ใช่pointerเคอร์เซอร์ที่ต้องการบ่อย) เนื่องจากจะถือว่า<a>เป็นจุดยึดไม่ใช่ลิงก์

ในแง่ของพฤติกรรมเมื่อระบุการกระทำโดยการนำทางhrefเบราว์เซอร์จะสนับสนุนการเปิดhrefในหน้าต่างแยกต่างหากโดยใช้ทางลัดหรือเมนูบริบท onclickนี้เป็นไปไม่ได้เมื่อระบุการดำเนินการผ่านทาง


อย่างไรก็ตามหากคุณถามว่าวิธีที่ดีที่สุดในการรับการกระทำแบบไดนามิกจากการคลิกวัตถุ DOM คืออะไรการแนบกิจกรรมโดยใช้ javascript แยกจากเนื้อหาของเอกสารเป็นวิธีที่ดีที่สุด คุณสามารถทำได้หลายวิธี วิธีทั่วไปคือการใช้ไลบรารี javascript เช่น jQuery เพื่อผูกเหตุการณ์:

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<a id="link" href="http://example.com/action">link text</a>
<script type="text/javascript">
    $('a#link').click(function(){ /* ... action ... */ })
</script>

9
ขอขอบคุณที่ยืนยันข้อสงสัยของฉันว่า "นี่" แตกต่างกันใน "href" กับ "onclick"
joonas.fi

17

ฉันใช้

Click <a nohref style="cursor:pointer;color:blue;text-decoration:underline"
onClick="alert('Hello World')">HERE</a>

ทางไกล แต่ก็ทำให้งานเสร็จ ใช้สไตล์ A เพื่อทำให้ง่ายขึ้นจากนั้นจะกลายเป็น:

<style> A {cursor:pointer;color:blue;text-decoration:underline; } </style> 
<a nohref onClick="alert('Hello World')">HERE</a>

10
+1 ยอดเยี่ยมจริง ๆ ! :-) ฉันไม่เคยได้ยินเกี่ยวกับnohrefคุณลักษณะมาก่อน นี่เป็นวิธีที่เหมาะสมที่สุดในการจัดการกับจาวาสคริปต์ สิ่งนี้เข้ากันได้กับ FF12 และ IE8 ดังนั้นผมจึงจะเข้ามาแทนที่ของฉันทั้งหมดโดยhref="JavaScript:void(0);" nohrefขอบคุณมาก. ไชโย
olibre

7
เบราว์เซอร์หลักไม่รองรับทำไมเราควรใช้มัน w3schools.com/tags/att_area_nohref.asp
hetaoblog

11
nohrefเป็นส่วนหนึ่งของareaแท็กไม่ใช่a! ตัวอย่างของคุณเหมือนกับ<a onClick="alert('Hello World')">HERE</a>
nZeus

6
อีกอันหนึ่ง "อย่าทำคำเตือนนี้" นี่เป็นคำแนะนำที่ไม่ได้มาตรฐานและไม่สมบูรณ์ nohrefไม่มีอยู่ในaแท็ก
โคลิน 't ฮาร์ต

11

นอกเหนือจากที่นี่แล้ว href จะปรากฏบนแถบสถานะของเบราว์เซอร์และไม่คลิก ฉันคิดว่ามันใช้งานไม่ง่ายเลยที่จะแสดงรหัสจาวาสคริปต์ที่นั่น


10

วิธีที่ดีที่สุดในการทำเช่นนี้คือ:

<a href="#" onclick="someFunction(e)"></a>

ปัญหาคือว่าสิ่งนี้จะเพิ่มแฮช (#) ที่ส่วนท้ายของ URL ของหน้าในเบราว์เซอร์ดังนั้นผู้ใช้ต้องคลิกปุ่มย้อนกลับสองครั้งเพื่อไปที่หน้าก่อนหน้าของคุณ เมื่อพิจารณาถึงสิ่งนี้คุณต้องเพิ่มรหัสบางอย่างเพื่อหยุดการเผยแพร่เหตุการณ์ ชุดเครื่องมือ javascript ส่วนใหญ่จะมีฟังก์ชั่นนี้อยู่แล้ว ตัวอย่างเช่นชุดเครื่องมือ dojo ใช้

dojo.stopEvent(event);

ทำเช่นนั้น


9
ฉันอยากจะเตือนว่าหากคุณใช้href="#"เบราว์เซอร์จะมองหาแท็กจุดยึดชื่อและเนื่องจากมันจะไม่พบมันก็จะทำให้หน้าต่างเลื่อนไปที่ด้านบนของหน้าสิ่งที่อาจไม่เห็นถ้า คุณอยู่ที่ด้านบนสุดแล้ว เพื่อหลีกเลี่ยงพฤติกรรมนี้ให้ใช้: href="javascript:;"แทน
alonso.torres

1
@ alonso.torres จุดที่ดี แต่นั่นเป็นเหตุผลที่ฉันพูดถึงการใช้ dojo.stopEvent () - มันจะหยุดการแพร่กระจายเหตุการณ์ / เดือดปุด ๆ และพฤติกรรมเริ่มต้นของการคลิกที่สมอ
linusthe3rd

7
แทน stopEvent ทำไมไม่ส่งคืน false (onclick = "someFunction (e); return false;")
stracktracer

10

คำตอบยอดนิยมคือการปฏิบัติที่ไม่ดีอย่างยิ่งหนึ่งไม่ควรเชื่อมโยงกับแฮชว่างเปล่าเพราะมันสามารถสร้างปัญหาตามท้องถนน

ดีที่สุดคือการผูกตัวจัดการเหตุการณ์กับองค์ประกอบตามที่คนอื่น ๆ ได้กล่าวไว้อย่างไรก็ตาม<a href="javascript:doStuff();">do stuff</a>ทำงานได้อย่างสมบูรณ์แบบในเบราว์เซอร์ที่ทันสมัยทุกครั้งและฉันใช้มันอย่างกว้างขวางเมื่อแสดงเทมเพลตเพื่อหลีกเลี่ยงการ rebind สำหรับแต่ละอินสแตนซ์ ในบางกรณีวิธีนี้ให้ประสิทธิภาพที่ดีขึ้น YMMV

สิ่งที่น่าสนใจอีกบิต

onclick& hrefมีพฤติกรรมที่แตกต่างเมื่อโทร javascript โดยตรง

onclickจะผ่านthisบริบทอย่างถูกต้องในขณะที่hrefไม่ได้หรือในคำอื่น ๆ<a href="javascript:doStuff(this)">no context</a>จะไม่ทำงานในขณะที่<a onclick="javascript:doStuff(this)">no context</a>จะ

hrefใช่ฉันละเว้น แม้ว่ามันจะไม่เป็นไปตามที่กำหนด แต่มันก็จะใช้ได้กับทุกเบราว์เซอร์ แต่โดยหลักแล้วมันควรจะมีวิธีhref="javascript:void(0);"การที่ดี


8

การมีjavascript:แอตทริบิวต์ที่ไม่เฉพาะสำหรับการเขียนสคริปต์เป็นวิธีที่ล้าสมัยของ HTML ในขณะที่ใช้งานได้ทางเทคนิคคุณยังคงกำหนดคุณสมบัติจาวาสคริปต์ให้กับคุณลักษณะที่ไม่ใช่สคริปต์ซึ่งไม่ใช่วิธีปฏิบัติที่ดี มันอาจล้มเหลวในเบราว์เซอร์เก่าหรือแม้แต่บางอันที่ทันสมัย ​​(โพสต์ฟอรัม googled ดูเหมือนจะบ่งบอกว่า Opera ไม่ชอบ 'javascript:' urls)

วิธีปฏิบัติที่ดีกว่าน่าจะเป็นวิธีที่สองคือใส่จาวาสคริปต์ของคุณลงในonclickแอตทริบิวต์ซึ่งจะถูกละเว้นหากไม่มีฟังก์ชันการทำงานของสคริปต์ วาง URL ที่ถูกต้องในฟิลด์ href (โดยทั่วไป '#') เพื่อเลือกสำรองสำหรับผู้ที่ไม่มี javascript


1
ฉันไม่เห็นความแตกต่างระหว่าง 'javascript:' href และ '# href ด้วยแอตทริบิวต์ onclick ทั้งคู่ไม่มีประโยชน์เท่ากันสำหรับเบราว์เซอร์ที่ไม่ได้เปิดใช้งาน JS
Harto

2
harto นั่นไม่ถูกต้องจริง '#' เป็นตัวบ่งชี้สำหรับลิงค์ที่มีชื่อไม่ใช่ตัวระบุจาวาสคริปต์ เป็น URL ที่ถูกต้องและไม่จำเป็นต้องมีการยอมรับ Javascript
zombat

8

มันใช้งานได้สำหรับฉันโดยใช้รหัสบรรทัดนี้:

<a id="LinkTest" title="Any Title"  href="#" onclick="Function(); return false; ">text</a>

7

วิธีนี้ใช้ได้ผล

<a href="#" id="sampleApp" onclick="myFunction(); return false;">Click Here</a>

3
ยินดีต้อนรับสู่ Stack Overflow! ในขณะที่ข้อมูลโค้ดนี้อาจแก้ไขคำถามรวมถึงคำอธิบายช่วยปรับปรุงคุณภาพของโพสต์ของคุณ จำไว้ว่าคุณกำลังตอบคำถามสำหรับผู้อ่านในอนาคตและคนเหล่านั้นอาจไม่ทราบสาเหตุของการแนะนำรหัสของคุณ โปรดอย่าพยายามทำให้รหัสของคุณแน่นเกินไปด้วยคำอธิบายที่อธิบายเนื่องจากจะช่วยลดความสามารถในการอ่านของทั้งรหัสและคำอธิบาย!
Goodbye StackExchange

2
รหัสนี้ใช้ไม่ได้ return: false ไม่ถูกต้อง มันควรจะกลับเท็จ
hbulens

5

โดยส่วนตัวแล้วฉันพบว่าการวางสายจาวาสคริปต์ในแท็ก HREF นั้นน่ารำคาญ ฉันมักจะไม่สนใจจริงๆว่ามีลิงค์ javascript หรือไม่และบางครั้งก็ต้องการเปิดสิ่งต่าง ๆ ในหน้าต่างใหม่ เมื่อฉันลองทำสิ่งนี้ด้วยหนึ่งในลิงค์ประเภทเหล่านี้ฉันจะได้หน้าว่างที่ไม่มีอะไรเลยและจาวาสคริปต์ในแถบตำแหน่งของฉัน อย่างไรก็ตามนี่คือ sidestepped บิตโดยใช้ onlick


3

อีกสิ่งหนึ่งที่ฉันสังเกตเห็นเมื่อใช้ "href" กับ javascript:

แอตทริบิวต์ใน "href" จะไม่ถูกเรียกใช้งานหากความแตกต่างของเวลาระหว่าง 2 คลิกค่อนข้างสั้น

ตัวอย่างเช่นลองเรียกใช้ตัวอย่างต่อไปนี้และดับเบิลคลิก (เร็ว!) ในแต่ละลิงก์ ลิงก์แรกจะถูกดำเนินการเพียงครั้งเดียว ลิงค์ที่สองจะถูกดำเนินการสองครั้ง

<script>
function myFunc() {
    var s = 0;
    for (var i=0; i<100000; i++) {
        s+=i;
    }
    console.log(s);
}
</script>
<a href="javascript:myFunc()">href</a>
<a href="#" onclick="javascript:myFunc()">onclick</a>

ทำซ้ำใน Chrome (ดับเบิลคลิก) และ IE11 (ด้วยการคลิกสามครั้ง) ใน Chrome หากคุณคลิกเร็วพอคุณสามารถคลิกได้ 10 ครั้งและมีการใช้งานเพียง 1 ฟังก์ชัน

Firefox ทำงานได้ดี


3

ก่อนอื่นการมี URL ในhrefนั้นดีที่สุดเพราะช่วยให้ผู้ใช้สามารถคัดลอกลิงก์เปิดในแท็บอื่น ฯลฯ

ในบางกรณี (เช่นไซต์ที่มีการเปลี่ยนแปลง HTML บ่อยครั้ง) มันไม่สามารถผูกลิงค์ทุกครั้งที่มีการอัพเดท

วิธีการผูกทั่วไป

ลิงก์ปกติ:

<a href="https://www.google.com/">Google<a/>

และสิ่งนี้สำหรับ JS:

$("a").click(function (e) {
    e.preventDefault();
    var href = $(this).attr("href");
    window.open(href);
    return false;
});

ประโยชน์ของวิธีนี้คือการแยกมาร์กอัปและลักษณะการทำงานที่สะอาดและไม่ต้องเรียกใช้ฟังก์ชันซ้ำในทุกลิงก์

ไม่มีวิธีผูกมัด

อย่างไรก็ตามหากคุณไม่ต้องการผูกทุกครั้งคุณสามารถใช้ onclick และส่งผ่านองค์ประกอบและเหตุการณ์เช่น:

<a href="https://www.google.com/" onclick="return Handler(this, event);">Google</a>

และนี่สำหรับ JS:

function Handler(self, e) {
    e.preventDefault();
    var href = $(self).attr("href");
    window.open(href);
    return false;
}

ข้อดีของวิธีนี้คือคุณสามารถโหลดลิงค์ใหม่ (เช่นผ่าน AJAX) ทุกครั้งที่คุณต้องการโดยไม่ต้องกังวลกับการผูกทุกครั้ง


1
 <hr>
            <h3 class="form-signin-heading"><i class="icon-edit"></i> Register</h3>
            <button data-placement="top" id="signin_student" onclick="window.location='signup_student.php'" id="btn_student" name="login" class="btn btn-info" type="submit">Student</button>
            <div class="pull-right">
                <button data-placement="top" id="signin_teacher" onclick="window.location='guru/signup_teacher.php'" name="login" class="btn btn-info" type="submit">Teacher</button>
            </div>
        </div>
            <script type="text/javascript">
                $(document).ready(function(){
                $('#signin_student').tooltip('show'); $('#signin_student').tooltip('hide');
                });
            </script>   
            <script type="text/javascript">
                $(document).ready(function(){
                $('#signin_teacher').tooltip('show'); $('#signin_teacher').tooltip('hide');
                });
            </script>   

0

ฉันพบว่า javascript: hrefs ไม่ทำงานเมื่อมีการฝังหน้าเว็บในคุณลักษณะเว็บเพจของ Outlook ซึ่งตั้งค่าโฟลเดอร์อีเมลไว้แทนที่จะแสดง URL

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.