Tôi có thể gọi jquery click () để theo liên kết <a> nếu tôi chưa ràng buộc một trình xử lý sự kiện với liên kết hoặc nhấp vào không?


175

Tôi có một bộ đếm thời gian trong JavaScript cần mô phỏng nhấp vào một liên kết để đi đến một trang khác sau khi hết thời gian. Để làm điều này tôi đang sử dụng click()chức năng của jQuery . Tôi đã sử dụng $().trigger()window.locationcũng có thể, và tôi có thể làm cho nó hoạt động như dự định với cả ba.

Tôi đã quan sát một số hành vi kỳ lạ với click()và tôi đang cố gắng hiểu điều gì xảy ra và tại sao.

Tôi đang sử dụng Firefox cho tất cả mọi thứ tôi mô tả trong câu hỏi này, nhưng tôi cũng quan tâm đến những trình duyệt khác sẽ làm gì với điều này.

Nếu tôi chưa sử dụng $('a').bind('click',fn)hoặc $('a').click(fn)để thiết lập một trình xử lý sự kiện, thì việc gọi $('a').click()dường như không làm gì cả. Nó không gọi trình xử lý mặc định của trình duyệt cho sự kiện này, vì trình duyệt không tải trang mới.

Tuy nhiên, nếu tôi đặt trình xử lý sự kiện trước, thì nó hoạt động như mong đợi, ngay cả khi trình xử lý sự kiện không làm gì cả.

$('a').click(function(){return true;}).click();

Điều này tải trang mới như thể tôi đã tự nhấp vào.

Vì vậy, câu hỏi của tôi có hai mặt: Đây có phải là hành vi kỳ lạ bởi vì tôi đang làm gì đó sai ở đâu đó? và tại sao gọi click()không làm gì với hành vi mặc định nếu tôi không tạo trình xử lý của riêng mình?

BIÊN TẬP:

Như Hoffman đã xác định khi anh ta cố gắng sao chép kết quả của tôi, kết quả mà tôi mô tả ở trên không thực sự xảy ra. Tôi không chắc điều gì đã gây ra các sự kiện tôi quan sát ngày hôm qua, nhưng tôi chắc chắn hôm nay rằng đó không phải là những gì tôi mô tả trong câu hỏi.

Vì vậy, câu trả lời là bạn không thể "giả" các nhấp chuột trong trình duyệt và tất cả các jQuery làm là gọi trình xử lý sự kiện của bạn. Bạn vẫn có thể sử dụng window.locationđể thay đổi trang và điều đó hoạt động tốt với tôi.


2
Có thể là một giải pháp: stackoverflow.com/questions/31687759/ từ
Sukrit Chhabra

Câu trả lời:


90

Thật thú vị, đây có lẽ là một "yêu cầu tính năng" (tức là lỗi) cho jQuery. Sự kiện nhấp chuột jQuery chỉ kích hoạt hành động nhấp (được gọi là sự kiện onClick trên DOM) trên phần tử nếu bạn liên kết một sự kiện jQuery với phần tử. Bạn nên truy cập danh sách gửi thư của jQuery ( http://forum.jquery.com/ ) và báo cáo điều này. Đây có thể là hành vi mong muốn, nhưng tôi không nghĩ vậy.

BIÊN TẬP:

Tôi đã thực hiện một số thử nghiệm và những gì bạn nói là sai, ngay cả khi bạn liên kết một chức năng với thẻ 'a', nó vẫn không đưa bạn đến trang web được chỉ định bởi thuộc tính href. Hãy thử đoạn mã sau:

<html>
<head>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
 <script>
  $(document).ready(function() {
   /* Try to dis-comment this:
   $('#a').click(function () {
    alert('jQuery.click()');
    return true;
   });
   */
  });
  function button_onClick() {
   $('#a').click();
  }
  function a_onClick() {
   alert('a_onClick');
  }
 </script>

</head>
<body>
 <input type="button" onclick="button_onClick()">
 <br>
 <a id='a' href='http://www.google.com' onClick="a_onClick()"> aaa </a>

</body>
</html> 

Nó không bao giờ truy cập google.com trừ khi bạn nhấp trực tiếp vào liên kết (có hoặc không có mã nhận xét). Cũng lưu ý rằng ngay cả khi bạn liên kết sự kiện nhấp vào liên kết, nó vẫn không chuyển sang màu tím khi bạn nhấp vào nút. Nó chỉ chuyển sang màu tím nếu bạn nhấp vào liên kết trực tiếp.

Tôi đã thực hiện một số nghiên cứu và có vẻ như .click không giả sử hoạt động với các thẻ 'a' vì trình duyệt không hỗ trợ "nhấp chuột giả" với javascript. Ý tôi là, bạn không thể "bấm" một yếu tố bằng javascript. Với các thẻ 'a', bạn có thể kích hoạt sự kiện onClick của nó nhưng liên kết sẽ không thay đổi màu sắc (thành màu liên kết đã truy cập, mặc định là màu tím trong hầu hết các trình duyệt). Vì vậy, sẽ không có ý nghĩa gì khi làm cho sự kiện nhấp chuột $ () hoạt động với các thẻ 'a' vì hành động đi tới thuộc tính href không phải là một phần của sự kiện onClick, nhưng được mã hóa cứng trong trình duyệt.


7
Tôi đã thử mã của bạn và nó thực hiện chính xác như bạn đã nói, nhưng mã của tôi thực hiện như tôi đã mô tả ở trên. Tôi sẽ làm thêm một số thử nghiệm và xem liệu tôi có thể đưa ra một ví dụ đơn giản về kết quả của tôi mà bạn có thể thử không.
Mnebuerquo

1
Đồng ý. Nó đã phải là một cái gì đó tôi đã làm sai. Tôi hoàn toàn chắc chắn tại thời điểm tôi đăng câu hỏi của mình rằng nó đang hoạt động, nhưng vì tôi đã thử ví dụ của bạn nên tôi không còn hoạt động nữa. Tôi sẽ chỉ quay lại sử dụng window.location để thay đổi trang và không thử giả mạo nhấp chuột.
Mnebuerquo

Thật vậy, click () không có nghĩa là tạo ra các nhấp chuột giả nhưng đôi khi chúng ta có thể sử dụng nó để nhấp vào nút hoặc biểu mẫu bằng cách tiêm javascript hoặc để thuận tiện trong khi tạo một phím nóng tạm thời trên đầu các chức năng javascript hiện có.
Hàng không Wang Wang

241

Tất nhiên, một lựa chọn khác là chỉ sử dụng javilla vanilla:

document.getElementById("a_link").click()

1
Điều này không hoạt động trong Safari và theo thông số kỹ thuật HTML, chỉ có các đầu vào cần thực hiện điều này.
Jeremy Kauffman

4
Đăng! Điều này không hoạt động! Nhưng tôi phải nói rằng nó không phải là javascript "vanilla" vì nó sử dụng một yếu tố jquery, vì vậy nó là javascript jquery jquery .... Nó hoạt động trong Firefox 24 và IE 10.
bgmCoder

@BGM, ok, nhưng click () không nằm trong phần tử jquery. Bạn có thể thay thế nó bằng getEuityById (".."). Click ()
Peter

wow vết thương đầy đủ, hoạt động như tôi mong đợi. +1 đã cho :). Đối với những người dùng khác, bạn cũng có thể sử dụng như: var lnk = document.getEuityById ("a_link"); if (lnk == null) {// làm một số ....} khác {lnk.click (); }
Iqbal

Đã thử nghiệm trên nhiều trình duyệt khác nhau, IE10 & Jquery 1.6.4 không thể xử lý việc này.
Hannes Schneidermayer

65

Nếu bạn nhìn vào mã cho $.clickhàm tôi sẽ đặt cược, có một câu lệnh có điều kiện kiểm tra xem phần tử có người nghe đã đăng ký cho clicksự kiện hay không trước khi nó diễn ra. Tại sao không chỉ lấy hrefthuộc tính từ liên kết và thay đổi vị trí trang theo cách thủ công?

 window.location.href = $('a').attr('href');

EDIT: Đây là lý do tại sao nó không nhấp qua, từ triggerchức năng, nguồn jQuery cho phiên bản 1.3.2:

 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
    if ( (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
        event.result = false;

    // Trigger the native events (except for clicks on links)
    if ( !bubbling && elem[type] && !event.isDefaultPrevented() && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
        this.triggered = true;
        try {
            elem[ type ]();
        // prevent IE from throwing an error for some hidden elements
        } catch (e) {}
    }

Sau khi nó gọi trình xử lý (nếu có) jQuery kích hoạt một sự kiện trên đối tượng. Tuy nhiên, nó chỉ gọi các trình xử lý riêng cho các sự kiện nhấp nếu phần tử không phải là một liên kết. Tôi đoán điều này đã được thực hiện có chủ đích vì một số lý do. Điều này phải đúng mặc dù trình xử lý sự kiện có được xác định hay không, vì vậy tôi không chắc tại sao trong trường hợp của bạn, việc gắn trình xử lý sự kiện lại khiến onClicktrình xử lý gốc được gọi. Bạn sẽ phải làm những gì tôi đã làm và bước qua thực thi để xem nó được gọi ở đâu.


Tôi chắc chắn có thể sử dụng window.location và the href như tôi đã đề cập trong câu hỏi. Tôi đang cố gắng hiểu những gì xảy ra trong jquery click () và nguyên nhân gây ra kết quả tôi quan sát được.
Mnebuerquo

Tôi đã chỉnh sửa câu trả lời của mình để hiển thị nơi trong nguồn jQuery, nó xử lý các lệnh gọi $ .click () trên các liên kết.
Ryan Lynch

2
window.location hoạt động, nhưng không đăng HTTP Referrer và phá vỡ nút quay lại.
Đuổi theo Seibert

5

Các trình xử lý nhấp chuột trên các thẻ neo là một trường hợp đặc biệt trong jQuery.

Tôi nghĩ rằng bạn có thể bị nhầm lẫn giữa sự kiện onclick của neo (được trình duyệt biết đến) và sự kiện nhấp chuột của đối tượng jQuery bao bọc khái niệm DOM của thẻ neo.

Bạn có thể tải xuống nguồn jQuery 1.3.2 tại đây .

Các phần có liên quan của nguồn là các dòng 2643-2645 (Tôi đã chia phần này thành nhiều dòng để dễ hiểu hơn):

// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
if (
     (!elem[type] || (jQuery.nodeName(elem, 'a') && type == "click")) && 
       elem["on"+type] && 
       elem["on"+type].apply( elem, data ) === false
   )
     event.result = false;

5

JS / jQuery không hỗ trợ hành vi mặc định của các liên kết "được nhấp" theo chương trình.

Những gì bạn có thể làm là tạo một biểu mẫu và gửi nó. Bằng cách này, bạn không phải sử dụng window.locationhoặc window.openthường bị các trình duyệt bật lên không mong muốn.

Tập lệnh này có 2 phương thức khác nhau: một phương pháp cố gắng mở 3 tab / cửa sổ mới (nó chỉ mở 1 trong IE và Chrome, thêm thông tin bên dưới) và một phương thức kích hoạt một sự kiện tùy chỉnh khi nhấp vào liên kết.

Đây là cách thực hiện:

HTML

<html>
<head>
    <script src="jquery-1.9.1.min.js" type="text/javascript"></script>
    <script src="script.js" type="text/javascript"></script>
</head>
<body>
    <button id="testbtn">Test</button><br><br>

    <a href="https://google.nl">GOOGLE</a><br>
    <a href="http://en.wikipedia.org/wiki/Main_Page">WIKI</a><br>
    <a href="https://stackoverflow.com/">SO</a>
</body>
</html>

jQuery (script.js)

$(function()
{ 
    // Try to open all 3 links by pressing the button
    // - Firefox opens all 3 links
    // - Chrome only opens 1 of them without popup warning
    // - IE only opens 1 of them WITH popup warning
    $("#testbtn").on("click", function()
    {
        $("a").each(function()
        {
            var form = $("<form></form>");
            form.attr(
            {
                id     : "formform",
                action : $(this).attr("href"),
                method : "GET",
                // Open in new window/tab
                target : "_blank"
            });

            $("body").append(form);
            $("#formform").submit();
            $("#formform").remove();
        });
    });

    // Or click the link and fire a custom event 
    // (open your own window without following the link itself)
    $("a").on("click", function()
    {
        var form = $("<form></form>");
        form.attr(
        {
            id     : "formform",
            // The location given in the link itself
            action : $(this).attr("href"), 
            method : "GET",
            // Open in new window/tab
            target : "_blank"              
        });

        $("body").append(form);
        $("#formform").submit();
        $("#formform").remove();

        // Prevent the link from opening normally
        return false;
    });

});

Những gì nó làm là cho mỗi phần tử liên kết:

  1. Tạo một hình thức
  2. Cung cấp cho nó thuộc tính
  3. Nối nó vào DOM để có thể gửi nó
  4. Gửi nó
  5. Xóa biểu mẫu khỏi DOM, xóa tất cả dấu vết * Chèn tiếng cười ác *

Bây giờ bạn đã tải tab / cửa sổ mới "https://google.nl"(hoặc bất kỳ URL nào bạn muốn, chỉ cần thay thế nó). Thật không may khi bạn cố gắng mở nhiều hơn một cửa sổ theo cách này, bạn sẽ nhận được một thanh thông Popup blockedbáo khi cố gắng mở cửa sổ thứ hai (cửa sổ đầu tiên vẫn được mở).


Thông tin thêm về cách tôi có được phương pháp này được tìm thấy ở đây:

Mở cửa sổ / tab mới mà không sử dụng window.openhoặcwindow.location.href


3

Kích hoạt một phần tử Hyperlink nằm bên trong phần tử mà bạn muốn kết nối jquery .click ()

<div class="TopicControl">
    <div class="articleImage">
       <a href=""><img src="" alt=""></a>
    </div>
</div>

Trong kịch bản của bạn, bạn nối vào thùng chứa chính mà bạn muốn sự kiện nhấp vào. Sau đó, bạn sử dụng phương pháp jquery tiêu chuẩn để tìm phần tử (loại, lớp, id) và kích hoạt nhấp chuột. Điều xảy ra là jquery nhập một hàm đệ quy để kích hoạt nhấp chuột và bạn phá vỡ hàm đệ quy bằng cách lấy hàm 'e' và stopPropagation () và trả về false vì bạn không muốn jquery làm bất cứ điều gì khác ngoài bắn liên kết.

$('.TopicControl').click(function (event) {
         $(this).find('a').click();
        event.stopPropagation();
        return false;
     });

Giải pháp thay thế là bọc các thùng chứa trong phần tử và đặt các thùng chứa bên trong thay vì của. Đặt các nhịp để khối hiển thị phù hợp với tiêu chuẩn w3c.


3

Bạn có thể sử dụng jQuery để chọn đối tượng jQuery cho phần tử đó. Sau đó, lấy phần tử DOM cơ bản và gọi click()phương thức của nó .

theo id

$("#my-link").each(function (index) { $(this).get(0).click() });

hoặc sử dụng jQuery để nhấp vào một loạt các liên kết theo lớp CSS

$(".my-link-class").each(function (index) { $(this).get(0).click() });

2

Nó không làm gì cả vì không có sự kiện nào bị ràng buộc với sự kiện này. Nếu tôi nhớ lại một cách chính xác, jQuery sẽ duy trì danh sách các trình xử lý sự kiện được ràng buộc với NodeLists cho hiệu năng và các mục đích khác.


2

Nếu bạn cần tính năng này cho một trường hợp hoặc rất ít casses. (toàn bộ ứng dụng của bạn không yêu cầu tính năng này) Tôi muốn rời khỏi jQuery như vậy (vì nhiều lý do, bao gồm khả năng cập nhật lên các phiên bản mới hơn, CDN, v.v.) và có cách giải quyết sau:

// For modren Browsers
$(ele).trigger("click");

// Relaying on Paul Irish's conditional class names http://bit.ly/HWIpAp (via HTML5 Boilerplate http://bit.ly/HUzi3I) where each IE version gets a class of its Version
$("html.ie7").length && (function(){
    var eleOnClickattr = $(ele).attr("onclick") 
    eval(eleOnClickattr);
  })()

1

Để mở siêu liên kết trong cùng một tab, hãy sử dụng:

$(document).on('click', "a.classname", function() {
    var form = $("<form></form>");
    form.attr(
    {
        id     : "formid",
        action : $(this).attr("href"),
        method : "GET",
    });

    $("body").append(form);
    $("#formid").submit();
    $("#formid").remove();
    return false;
});
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.