Sự khác biệt giữa các phương pháp đặt mã JavaScript khác nhau trong <a> là gì?


87

Tôi đã thấy các phương pháp đặt mã JavaScript vào <a>thẻ sau đây:

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>

Tôi hiểu ý tưởng cố gắng đặt một URL hợp lệ thay vì chỉ mã JavaScript, đề phòng trường hợp người dùng chưa bật JavaScript. Nhưng với mục đích của cuộc thảo luận này, tôi cần giả sử JavaScript đã được bật (họ không thể đăng nhập nếu không có nó).

Cá nhân tôi thích tùy chọn 2 vì nó cho phép bạn xem những gì sẽ được chạy – đặc biệt hữu ích khi gỡ lỗi trong đó có các tham số được truyền cho hàm. Tôi đã sử dụng nó một chút và không tìm thấy sự cố trình duyệt.

Tôi đã đọc rằng mọi người đề xuất 4, bởi vì nó cung cấp cho người dùng một liên kết thực để theo dõi, nhưng thực sự, # không phải là "thực". Nó sẽ hoàn toàn không đi đâu cả.

Có cái nào không được hỗ trợ hoặc thực sự không tốt, khi bạn biết người dùng đã bật JavaScript?

Câu hỏi liên quan: Href cho các liên kết JavaScript: “#” hoặc “javascript: void (0)”? .


Vấn đề nhỏ về cú pháp: Lựa chọn số 2 phải là - <a href="javascript:DoSomething();"> liên kết </a> mà không có "return"
DRosenfeld

Vui lòng thay đổi câu trả lời được chấp nhận thành câu trả lời @eyelidless. Tôi nghĩ đó là cách tiếp cận tốt nhất, bởi vì nó quan tâm đến ngữ nghĩa.
Michał Perłakowski

Câu trả lời:


69

Tôi khá thích bài viết Các phương pháp hay nhất về Javascript của Matt Kruse . Trong đó, ông nói rằng việc sử dụng hrefphần này để thực thi mã JavaScript là một ý tưởng tồi. Mặc dù bạn đã tuyên bố rằng người dùng của mình phải bật JavaScript, không có lý do gì bạn không thể có một trang HTML đơn giản mà tất cả các liên kết JavaScript của bạn có thể trỏ đến cho hrefphần của họ trong trường hợp ai đó tắt JavaScript sau khi đăng nhập. Tôi thực sự khuyến khích bạn vẫn cho phép cơ chế dự phòng này. Những thứ như thế này sẽ tuân thủ "các phương pháp hay nhất" và hoàn thành mục tiêu của bạn:

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

4
vì giá trị href sẽ được hiển thị cho người dùng trên thanh trạng thái? (thanh ở dưới cùng) Tôi sẽ xem xét sử dụng liên kết thân thiện với người dùng hơn một chút, ví dụ. "js.html? doSomething" trang vẫn có thể là html tĩnh. Bằng cách này, người dùng sẽ thấy rõ ràng sự khác biệt giữa các liên kết.
Gene

7
Bạn có thể ghi đè giá trị này bằng thuộc tính title, ví dụ: <a href="javascript_required.html" title="Does Something" onclick="doSomething(); return false;"> bắt đầu </a>
Trình biên dịch dễ thấy

Cách tốt nhất là đăng nhập các yêu cầu vào trang javascript_required.html và ghi lại hàm gây ra lỗi.
Timo Huovinen

2
Bạn đã nghĩ đến hậu quả đối với SEO chưa?
DanielBlazquez 14/09/12

Trang javascripttoolbox.com của Matt Kruse dường như đang ngoại tuyến và đang được rao bán.
showdev

10

Tại sao bạn làm điều này khi bạn có thể sử dụng addEventListener/ attachEvent? Nếu không có- hreftương đương, không sử dụng an <a>, sử dụng a <button>và tạo kiểu cho phù hợp.


9
sử dụng một nút thay vì liên kết không phải là một lựa chọn khả thi trong nhiều trường hợp.
nickf 29/10/08

2
Vì nó trông thật xấu xí. Bạn có thể thêm một biểu tượng bên cạnh liên kết. Chúng khó định dạng giống nhau trên các trình duyệt. Và nói chung, mọi người đang chuyển sang các liên kết thay vì các nút - hãy nhìn vào hầu hết các ngăn xếp trên luồng.
Darryl Hein

2
Nó trông xấu xí? Nó trông giống như bất cứ điều gì bạn muốn nó trông như thế nào. Trên thực tế, tôi nghĩ rằng các nút thực sự có tính linh hoạt về kiểu dáng hơn so với các liên kết, ở chỗ chúng nằm trong dòng nhưng có thể đệm đúng cách trên các trình duyệt. Bất cứ điều gì có thể được thực hiện với một liên kết có thể được thực hiện bằng một nút, liên quan đến CSS.
mí mắt.

2
Khoảng cách không thể tập trung vào bàn phím.
bobince

3
Và nút (thở hổn hển) đúng về mặt ngữ nghĩa. Span là vô nghĩa về mặt ngữ nghĩa. Một nút chính xác là những gì tác giả dự định sử dụng, về mặt ngữ nghĩa.
mí mắt. 29/10/08

5

Bạn quên một phương pháp khác:

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

Với mã JavaScript:

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

Tôi không thể bình luận về tùy chọn nào có hỗ trợ tốt nhất hoặc tùy chọn nào là tốt nhất về mặt ngữ nghĩa, nhưng tôi chỉ nói rằng tôi thích phong cách này hơn vì nó tách nội dung của bạn khỏi mã JavaScript của bạn. Nó giữ tất cả mã JavaScript lại với nhau, dễ bảo trì hơn nhiều (đặc biệt nếu bạn đang áp dụng điều này cho nhiều liên kết) và bạn thậm chí có thể đặt nó vào một tệp bên ngoài, sau đó có thể được đóng gói để giảm kích thước tệp và lưu vào bộ nhớ cache của trình duyệt khách.


7
Nếu bạn có 20 hoặc 30 liên kết khác nhau với JS, điều này có thể trở nên khá tẻ nhạt và kết thúc với rất nhiều JS.
Darryl Hein

không còn tẻ nhạt hơn việc lội qua HTML để thay đổi javascript. . ... hoặc bạn có thể sử dụng giống như jQuery có thể dễ dàng thay đổi các sự kiện trên nhiều yếu tố cùng một lúc ... $ ( '# thực đơn') click (function () {..})
nickf

1
@JKirchartz Tôi không hiểu nó rao giảng như thế nào nếu có lý do đằng sau câu trả lời. Nếu bạn đọc câu hỏi, nó thực sự là "cái nào trong số 4 cái này là tốt nhất", và tôi chỉ chỉ ra rằng có một lựa chọn khác mà anh ấy đã không xem xét.
nickf

Không quan tâm, trololo, khi lựa chọn giữa ABC và D, người ta không chọn E.
JKirchartz

3
@JKirchartz Vâng, tôi không nghĩ bạn thực sự hiểu được mục đích của Stack Overflow. Nếu ai đó hỏi "Cái nào tốt hơn để xây dựng một ứng dụng web trong: Cobol hay Fortran?" Có thể chấp nhận được khi nói với người đó rằng họ chưa xem xét tất cả các khả năng. Câu hỏi rõ ràng không phải hỏi "điều nào trong số bốn điều này là tốt nhất".
nickf

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

Tôi sẽ làm điều này, hoặc:

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

Tuỳ thuộc vào tình hình. Đối với các ứng dụng lớn hơn, ứng dụng thứ hai là tốt nhất vì sau đó nó hợp nhất mã sự kiện của bạn.


Nếu bạn có 20 hoặc 30 liên kết khác nhau với JS, điều này có thể trở nên khá tẻ nhạt và kết thúc với rất nhiều JS.
Darryl Hein

và các lỗi len lỏi vào mã của bạn có thể RẤT khó gỡ lỗi. Những lỗi này xuất hiện rất dễ dàng, bằng chứng là ví dụ đầu tiên của bạn. :)
nickf 29/10/08

1

Phương pháp # 2 có lỗi cú pháp trong FF3 và IE7. Tôi thích phương pháp # 1 và # 3 hơn, vì # 4 làm bẩn URI bằng '#' mặc dù ít gây ra việc nhập hơn ... Rõ ràng, như được lưu ý bởi các phản hồi khác, giải pháp tốt nhất là tách html khỏi xử lý sự kiện.


Phương pháp # 2 của cái gì? Các câu hỏi không theo thứ tự như khi BẠN nhìn thấy chúng.
Diodeus - James MacFarlane 29/10/08

Phương pháp số 4 sẽ không làm rối URI nếu bạn chắc chắn return false. Vì lý do đó, phương pháp số 4 có lẽ là tốt nhất (trong số những phương pháp được liệt kê).
Már Örlygsson 29/10/08

2
@Diodeus, tôi tin rằng Pier đang đề cập đến danh sách được đánh số trong câu hỏi , trên thực tế đã có từ khi câu hỏi được đăng ngay từ đầu.
mí mắt,

1

Một điểm khác biệt mà tôi nhận thấy giữa điều này:

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

và điều này:

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

đó là nếu trong cả hai trường hợp bạn có:

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

thì đối với ví dụ đầu tiên, act2sẽ chạy trước act1và trong ví dụ thứ hai, nó sẽ theo chiều ngược lại.


1

Chỉ các trình duyệt hiện đại

<!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>

Qua trình duyệt

<!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>

Bạn có thể chạy điều này trước khi tài liệu sẵn sàng, nhấp vào các nút sẽ hoạt động vì chúng tôi đính kèm sự kiện vào tài liệu.

Nguồn:

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.