อะไรคือความแตกต่างระหว่างวิธีการต่างๆในการใส่โค้ด JavaScript ใน <a>?


87

ฉันได้เห็นวิธีการต่อไปนี้ในการใส่โค้ด JavaScript ใน<a>แท็ก:

function DoSomething() { ... return false; }
  1. <a href="javascript:;" onClick="return DoSomething();">link</a>
  2. <a href="javascript:DoSomething();">link</a>
  3. <a href="javascript:void(0);" onClick="return DoSomething();">link</a>
  4. <a href="#" onClick="return DoSomething();">link</a>

ฉันเข้าใจแนวคิดในการพยายามใส่ URL ที่ถูกต้องแทนที่จะใส่โค้ด JavaScript ในกรณีที่ผู้ใช้ไม่ได้เปิดใช้งาน JavaScript แต่สำหรับจุดประสงค์ของการสนทนานี้ฉันต้องถือว่า JavaScript เปิดใช้งาน (พวกเขาไม่สามารถเข้าสู่ระบบได้หากไม่มี)

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

ฉันได้อ่านที่มีคนแนะนำ 4 เพราะมันทำให้ผู้ใช้มีลิงค์ที่แท้จริงเพื่อติดตาม แต่จริงๆ # ไม่ใช่ "ของจริง" มันจะไม่ไปไหนอย่างแน่นอน

มีสิ่งที่ไม่รองรับหรือไม่ดีจริงๆเมื่อคุณรู้ว่าผู้ใช้เปิดใช้งาน JavaScript?

คำถามที่เกี่ยวข้อง: Href สำหรับลิงก์ JavaScript:“ #” หรือ“ javascript: void (0)”? .


ปัญหาด้านไวยากรณ์
เล็กน้อย

โปรดเปลี่ยนคำตอบที่ยอมรับเป็นคำตอบ @eyelidlessness ฉันคิดว่าเป็นแนวทางที่ดีที่สุดเพราะให้ความสำคัญกับความหมาย
MichałPerłakowski

คำตอบ:


69

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

<a href="javascript_required.html" onclick="doSomething(); return false;">go</a>

4
เนื่องจากค่า href จะแสดงให้ผู้ใช้เห็นในแถบสถานะ? (แถบด้านล่าง) ฉันจะพิจารณาใช้ลิงค์ที่เป็นมิตรกับผู้ใช้มากขึ้นเช่น "js.html? doSomething" หน้ายังคงเป็น html แบบคงที่ได้ วิธีนี้ผู้ใช้จะเห็นความแตกต่างระหว่างลิงก์อย่างชัดเจน
ยีน

7
คุณสามารถแทนที่ค่านี้ด้วยแอตทริบิวต์ title ได้เช่น <a href="javascript_required.html" title="Does Something" onclick="doSomething(); return false;"> go </a>
Conspicuous Compiler

ควรเป็นแนวทางปฏิบัติที่ดีที่สุดในการบันทึกคำขอไปยังหน้า javascript_required.html และบันทึกฟังก์ชันที่ทำให้เกิดข้อผิดพลาด
Timo Huovinen

2
คุณเคยคิดถึงผลที่ตามมาของ SEO หรือไม่?
DanielBlazquez

javascripttoolbox.comของ Matt Kruse ดูเหมือนจะออฟไลน์และขาย
showdev

10

ทำไมคุณถึงทำเช่นนี้เมื่อคุณสามารถใช้addEventListener/ attachEvent? หากไม่มีhref- เทียบเท่าอย่าใช้ an <a>ใช้ a <button>และจัดรูปแบบตามนั้น


9
การใช้ปุ่มแทนลิงก์ไม่ใช่ตัวเลือกที่เป็นไปได้ในหลาย ๆ กรณี
nickf

2
เพราะมันดูน่าเกลียด. คุณสามารถเพิ่มไอคอนข้างลิงค์ มันยากที่จะจัดรูปแบบเหมือนกันในเบราว์เซอร์ และโดยทั่วไปผู้คนจะย้ายไปที่ลิงก์แทนที่จะใช้ปุ่ม - ดูที่สแต็กโอเวอร์โฟลว์ส่วนใหญ่
Darryl Hein

2
มันดูน่าเกลียด? ดูเหมือนว่าอะไรก็ตามที่คุณต้องการให้ดูเหมือน อันที่จริงฉันคิดว่าปุ่มมีความยืดหยุ่นในรูปแบบมากกว่าลิงก์เนื่องจากเป็นแบบอินไลน์ แต่สามารถใช้ช่องว่างระหว่างเบราว์เซอร์ได้อย่างเหมาะสม สิ่งใดก็ตามที่สามารถทำได้ด้วยลิงก์สามารถทำได้โดยใช้ปุ่มเกี่ยวกับ CSS
เปลือกตา

2
Span ไม่สามารถเน้นแป้นพิมพ์ได้
bobince

3
และปุ่ม (อ้าปากค้าง) ถูกต้องตามความหมาย Span ไม่มีความหมายในเชิงความหมาย ปุ่มคือว่าสิ่งที่ผู้เขียนตั้งใจที่จะใช้ความหมาย
เปลือกตา

5

คุณลืมวิธีอื่น:

5: <a href="#" id="myLink">Link</a>

ด้วยรหัส JavaScript:

document.getElementById('myLink').onclick = function() {
    // Do stuff.
};

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


7
หากคุณมีลิงก์ที่แตกต่างกัน 20 หรือ 30 ลิงก์กับ JS สิ่งนี้อาจทำให้น่าเบื่อและจบลงด้วย JS จำนวนมาก
Darryl Hein

ไม่น่าเบื่อไปกว่าการลุยผ่าน HTML เพื่อเปลี่ยนจาวาสคริปต์ ... หรือคุณอาจใช้ jQuery ซึ่งสามารถเปลี่ยนเหตุการณ์ในหลาย ๆ องค์ประกอบพร้อมกันได้อย่างง่ายดาย ... $ ('# menu a') คลิก (function () {.. })
nickf

1
@JKirchartz ฉันไม่เห็นว่ามันเทศน์อย่างไรหากมีเหตุผลเบื้องหลังคำตอบ หากคุณอ่านคำถามแล้วมันเป็น "4 ข้อใดดีที่สุด" และฉันเพิ่งชี้ให้เห็นว่ามีตัวเลือกอื่นที่เขาไม่ได้พิจารณา
nickf

ไม่ต้องสนใจ trololo เมื่อเลือกระหว่าง ABC และ D ไม่มีใครเลือก E.
JKirchartz

3
@JKirchartz ใช่ฉันไม่คิดว่าคุณจะได้รับจุดประสงค์ของ Stack Overflow จริงๆ หากมีคนถามว่า "สร้างเว็บแอปใน Cobol หรือ Fortran แบบไหนดีกว่ากัน" เป็นเรื่องที่ยอมรับได้ที่จะบอกบุคคลนั้นว่าพวกเขาไม่ได้พิจารณาถึงความเป็นไปได้ทั้งหมด คำถามที่ชัดเจนไม่ได้ถามว่า " สิ่งใดดีที่สุดจากสี่สิ่งนี้เท่านั้น "
nickf

3
<a href="#" onClick="DoSomething(); return false;">link</a>

ฉันจะทำสิ่งนี้หรือ:

<a href="#" id = "Link">link</a>
(document.getElementById("Link")).onclick = function() {
    DoSomething();
    return false;
};

ขึ้นอยู่กับสถานการณ์ สำหรับแอปขนาดใหญ่แอปที่สองจะดีที่สุดเพราะจะรวมรหัสเหตุการณ์ของคุณ


หากคุณมีลิงก์ที่แตกต่างกัน 20 หรือ 30 ลิงก์กับ JS สิ่งนี้อาจทำให้น่าเบื่อและจบลงด้วย JS จำนวนมาก
Darryl Hein

และข้อบกพร่องที่คืบคลานเข้ามาในโค้ดของคุณอาจแก้ไขได้ยากมาก จุดบกพร่องเหล่านี้ปรากฏได้ง่ายมากดังที่เห็นได้จากตัวอย่างแรกของคุณ :)
nickf

1

วิธีที่ 2 มีข้อผิดพลาดทางไวยากรณ์ใน FF3 และ IE7 ฉันชอบวิธี # 1 และ # 3 เพราะ # 4 ทำให้ URI สกปรกด้วย '#' แม้ว่าจะทำให้พิมพ์น้อยลง ... เห็นได้ชัดจากคำตอบอื่น ๆ วิธีแก้ปัญหาที่ดีที่สุดคือ html แยกจากการจัดการเหตุการณ์


วิธีที่ 2 ของอะไร? คำถามไม่ได้เรียงลำดับเหมือนตอนที่คุณเห็น
Diodeus - James MacFarlane

วิธีที่ 4 จะไม่เลอะ URI return falseถ้าคุณให้แน่ใจว่า ด้วยเหตุผลดังกล่าววิธี # 4 น่าจะดีที่สุด (จากที่ระบุไว้)
MárÖrlygsson

2
@ Diodeus ฉันเชื่อว่า Pier อ้างถึงรายการที่มีหมายเลขในคำถามซึ่งในความเป็นจริงมีตั้งแต่คำถามถูกโพสต์ในตอนแรก
เปลือกตา

1

ความแตกต่างอย่างหนึ่งที่ฉันสังเกตเห็นระหว่างสิ่งนี้:

<a class="actor" href="javascript:act1()">Click me</a>

และนี่:

<a class="actor" onclick="act1();">Click me</a>

คือถ้าในทั้งสองกรณีคุณมี:

<script>$('.actor').click(act2);</script>

จากนั้นสำหรับตัวอย่างแรกact2จะทำงานก่อนact1และในตัวอย่างที่สองจะเป็นอีกทางหนึ่ง


1

เบราว์เซอร์สมัยใหม่เท่านั้น

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
(function(doc){
    var hasClass = function(el,className) {
        return (' ' + el.className + ' ').indexOf(' ' + className + ' ') > -1;
    }
    doc.addEventListener('click', function(e){
      if(hasClass(e.target, 'click-me')){
          e.preventDefault();
          doSomething.call(e.target, e);
      }
    });
})(document);

function doSomething(event){
  console.log(this); // this will be the clicked element
}
</script>
<!--... other head stuff ...-->
</head>
<body>

<!--buttons can be used outside of forms https://stackoverflow.com/a/14461672/175071 -->
<button class="click-me">Button 1</button>
<input class="click-me" type="button" value="Button 2">

</body>
</html>

ข้ามเบราว์เซอร์

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
(function(doc){
    var cb_addEventListener = function(obj, evt, fnc) {
        // W3C model
        if (obj.addEventListener) {
            obj.addEventListener(evt, fnc, false);
            return true;
        } 
        // Microsoft model
        else if (obj.attachEvent) {
            return obj.attachEvent('on' + evt, fnc);
        }
        // Browser don't support W3C or MSFT model, go on with traditional
        else {
            evt = 'on'+evt;
            if(typeof obj[evt] === 'function'){
                // Object already has a function on traditional
                // Let's wrap it with our own function inside another function
                fnc = (function(f1,f2){
                    return function(){
                        f1.apply(this,arguments);
                        f2.apply(this,arguments);
                    }
                })(obj[evt], fnc);
            }
            obj[evt] = fnc;
            return true;
        }
        return false;
    };
    var hasClass = function(el,className) {
        return (' ' + el.className + ' ').indexOf(' ' + className + ' ') > -1;
    }

    cb_addEventListener(doc, 'click', function(e){
      if(hasClass(e.target, 'click-me')){
          e.preventDefault ? e.preventDefault() : e.returnValue = false;
          doSomething.call(e.target, e);
      }
    });
})(document);

function doSomething(event){
  console.log(this); // this will be the clicked element
}
</script>
<!--... other head stuff ...-->
</head>
<body>

<!--buttons can be used outside of forms https://stackoverflow.com/a/14461672/175071 -->
<button class="click-me">Button 1</button>
<input class="click-me" type="button" value="Button 2">

</body>
</html>

คุณสามารถเรียกใช้สิ่งนี้ก่อนที่เอกสารจะพร้อมคลิกปุ่มต่างๆจะทำงานได้เนื่องจากเราแนบเหตุการณ์ไปกับเอกสาร

แหล่งที่มา:

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