Trong jQuery, làm cách nào để phân biệt giữa nhấp chuột có lập trình và nhấp chuột của người dùng?


91

Giả sử tôi đã xác định một trình xử lý nhấp chuột:

$("#foo").click(function(e){

});

Làm cách nào tôi có thể, trong trình xử lý hàm, cho biết sự kiện được kích hoạt theo chương trình hay bởi người dùng?


Chương trình bắt đầu sự kiện theo chương trình như thế nào?
Clayton

5
Tại sao bạn cần phân biệt các trường hợp?
Damien_The_Un Believer

@Clayton: $x.click()hoặc $x.trigger('click').
mu quá ngắn

Tôi đã gặp phải tình huống với thanh trượt hình ảnh tự động cuộn qua các hình ảnh và làm như vậy bằng cách kích hoạt nhấp chuột vào mục điều hướng chính xác được liên kết với hình ảnh. Vấn đề là, khi người dùng nhấp vào điều hướng, vòng quay tự động sẽ dừng lại.
Kasapo

2
Điều này hoạt động trong firefox, chrome và IE9 mới nhất. Tại sao không chấp nhận câu trả lời dưới đây với lượt bình chọn cao nhất ?? @kevino
OZZIE

Câu trả lời:


119

Bạn có thể nhìn vào đối tượng sự kiện e. Nếu sự kiện này được kích hoạt bởi một nhấp chuột thực tế, bạn sẽ có những thứ như clientX, clientY, pageX, pageYvv bên trong evà họ sẽ có con số; những con số này liên quan đến vị trí chuột khi kích hoạt nhấp chuột nhưng chúng có thể sẽ hiện diện ngay cả khi nhấp chuột được thực hiện thông qua bàn phím. Nếu sự kiện được kích hoạt trước $x.click()đó thì bạn sẽ không có các giá trị vị trí thông thường e. Bạn cũng có thể nhìn vào originalEventtài sản , tài sản đó sẽ không có nếu sự kiện đến từ $x.click().

Có thể như thế này:

$("#foo").click(function(e){
    if(e.hasOwnProperty('originalEvent'))
        // Probably a real click.
    else
        // Probably a fake click.
});

Và đây là một hộp cát nhỏ để chơi với: http://jsfiddle.net/UtzND/


4
Thật tuyệt vời ... Tôi chỉ nghĩ với bản thân "có thể các sự kiện được kích hoạt jQuery không có thông tin vị trí chuột"! w00t!
Kasapo

2
Điều này có thể bị đánh bại trong các trình duyệt hỗ trợ createEvent. jsfiddle.net/UtzND/26
Joe Enzminger

2
@JoeEnzminger vâng nhưng tại sao bạn lại đánh bại kịch bản của chính mình để nói chuyện ...?
OZZIE

3
Tôi lo lắng về việc một tập lệnh của bên thứ ba tạo ra một sự kiện nhấp chuột và tập lệnh của tôi xử lý nó dựa trên giả định rằng nó do người dùng tạo (một nhấp chuột thực tế).
Joe Enzminger

2
@JoeEnzminger: Tất cả cược sẽ tắt khi mã của bạn ở trong trình duyệt, bạn không thể làm gì mà không thể bị đánh bại bởi một người đủ thông minh. Tôi nghĩ điều tốt nhất bạn có thể làm là kiểm tra một loạt thứ: Có không originalEvent? Nó có phải là loại điều phù hợp? Có tọa độ ở đâu không? Các tọa độ có nhất quán không? Có tọa độ bên trong #fookhông? ...
mu quá ngắn

44

Bạn có thể sử dụng một tham số bổ sung như đã nêu trong hướng dẫn kích hoạt jQuery :

$("#foo").click(function(e, from){
    if (from == null)
        from = 'User';
    // rest of your code
});

$('#foo').trigger('click', ['Trigger']);

3
Vấn đề duy nhất tôi thấy với điều này là bạn không thể phân biệt giữa một lần nhấp bình thường và $x.click(), .click()người gọi phải nói rõ với bạn rằng họ đang giả mạo. Đây có thể là một vấn đề hoặc không phụ thuộc vào những gì Kevin Owocki đang làm.
mu quá ngắn

1
@mu: Tôi hoàn toàn không hiểu sự khác biệt của mình giữa một "bình thường" nhấp chuột và (người dùng?) $x.click()mà là eventHandler (đối với người sử dụng nhấp chuột, đó có thể là "bình thường")
Shikiryu

1
Sự khác biệt là một cái đến từ người dùng nhưng cái khác đến từ phần mềm. Nhấp chuột giả có thể đến từ một plugin hoặc một số mã khác không thể sửa đổi để thêm các đối số bổ sung. Tôi không chỉ trích giải pháp của bạn, chỉ lưu ý một số lỗ hổng có thể xảy ra.
mu quá ngắn

Mặc dù mu là chính xác và điều này sẽ không hoạt động trong mọi tình huống, nhưng nó chính xác là những gì tôi đang tìm kiếm, cảm ơn bạn! Tôi không biết mình có thể chuyển tham số bổ sung như var, nhưng đó chính xác là những gì tôi cần để kiểm tra các nhấp chuột "thực" trong giao diện người dùng phức tạp coi một số nhấp chuột "thực" là có lập trình. Cảm ơn cả hai giải pháp vô cùng hữu ích!
Phil

9

Có một câu hỏi khác đã được trả lời.

Làm thế nào để phát hiện một nhấp chuột () là một nhấp chuột hoặc được kích hoạt bởi một số mã?

Sử dụng thuộc whichtính của đối tượng sự kiện. Nó phải undefineddành cho các sự kiện do mã kích hoạt

$("#someElem").click(function(e) {
    if (e.which) {
        // Actually clicked
    } else {
        // Triggered by code
    }
});

Ví dụ về JsFiddle - http://jsfiddle.net/interdream/frw8j/

Hy vọng nó giúp!


2
Không phải lúc nào cũng hoạt động. Ví dụ: selectsẽ cung cấp cho một e.which==undefinedthậm chí cho một sự kiện chính hãng.
JNF

5

Tôi đã thử tất cả các giải pháp trên nhưng không có gì hiệu quả trong trường hợp của tôi. Giải pháp dưới đây đã làm việc cho tôi. Hy vọng nó cũng sẽ giúp bạn.

$(document).ready(function(){
  //calling click event programmatically
    $("#chk1").trigger("click");
});

$(document).on('click','input[type=checkbox]',function(e) {
		if(e.originalEvent.isTrusted==true){
			alert("human click");
		}
		else{
			alert("programmatically click");
		}
    
    });
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js">
</script>

<input type="checkbox" id="chk1" name="chk1" >Chk1</input>
<input type="checkbox" id="chk2" name="chk2" >Chk2</input>
<input type="checkbox" id="chk3" name="chk3" >Chk3</input>


4

DOM Mức 3 chỉ định event.isTrusted. Điều này hiện chỉ được hỗ trợ trong IE9 + và Firefox (dựa trên các thử nghiệm của tôi. Tôi cũng đã đọc (mặc dù chưa được nghiên cứu kỹ lưỡng) rằng nó có thể bị ghi đè trong một số trình duyệt và có lẽ chưa sẵn sàng 100% để thực sự đáng tin cậy (thật không may).

Đây là phiên bản sửa đổi của @ mu's fiddle hoạt động trên IE và Firefox.


Điểm tốt. Tôi không nghĩ rằng bất cứ thứ gì sẽ chắc chắn 100%. Bạn sẽ phải kết hợp một số thử nghiệm để xem liệu isTrustedcó được hỗ trợ và không thể ghi. Tôi nghĩ câu trả lời thực sự phụ thuộc vào lý do tại sao đằng sau câu hỏi này và chúng tôi chưa bao giờ tìm ra lý do tại sao.
mu quá ngắn

@mu, tôi đến với câu hỏi này sau khi hỏi một câu tương tự, nhưng tổng quát hơn. Trường hợp "tại sao" của tôi là tôi muốn đảm bảo rằng tôi chỉ thực hiện một hành động (một giao dịch tài chính, dù là một giao dịch nhỏ) với người dùng đã thực hiện hành động khẳng định trực tiếp trên trang.
Joe Enzminger

1

Giải pháp Vanila js:

document.querySelector('button').addEventListener('click', function (e){
    if(e.isTrusted){
        // real click.
    }else{
        // programmatic click
    }
});

-1

Sẽ không tham gia vào các cuộc thảo luận hữu trí tuệ, các mã mà làm việc cho tôi để lọc .click().trigger('click')là-

$(document).on('click touchstart', '#my_target', function(e) {
    if (e.pageX && e.pageY) { // To check if it is not triggered by .click() or .trigger('click')
        //Then code goes here
    }
});
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.