ใน jQuery ฉันจะทราบได้อย่างไรระหว่างการคลิกแบบเป็นโปรแกรมกับผู้ใช้


91

สมมติว่าฉันมีตัวจัดการคลิกที่กำหนดไว้:

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

});

ภายในตัวจัดการฟังก์ชันจะบอกได้อย่างไรว่าเหตุการณ์นั้นถูกเริ่มโดยโปรแกรมหรือโดยผู้ใช้


โปรแกรมดำเนินการอย่างไรเกี่ยวกับการเริ่มต้นเหตุการณ์โดยใช้โปรแกรม
Clayton

5
ทำไมคุณต้องแยกแยะกรณี?
Damien_The_Unbeliever

@Clayton: $x.click()หรือ$x.trigger('click').
สั้นเกินไป

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

2
ใช้งานได้กับ firefox, chrome และ IE9 ล่าสุด ทำไมไม่ตอบรับคำตอบด้านล่างด้วยคะแนนโหวตสูงสุด ?? @kevino
OZZIE

คำตอบ:


119

eคุณอาจจะมีลักษณะที่วัตถุเหตุการณ์ ถ้าเหตุการณ์ถูกเรียกโดยการคลิกที่จริงคุณจะมีสิ่งที่ชอบclientX, clientY, pageX, pageYฯลฯ ภายในeและพวกเขาจะหมายเลข; ตัวเลขเหล่านี้เกี่ยวข้องกับตำแหน่งของเมาส์เมื่อมีการเรียกใช้การคลิก แต่อาจจะปรากฏแม้ว่าการคลิกจะเริ่มต้นผ่านแป้นพิมพ์ หากเหตุการณ์ถูกทริกเกอร์$x.click()คุณจะไม่มีค่าตำแหน่งปกติในe. นอกจากนี้คุณยังสามารถดูที่originalEventคุณสมบัติ$x.click()ที่ไม่ควรจะมีหากมีเหตุการณ์มาจาก

อาจจะเป็นดังนี้:

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

และนี่คือแซนด์บ็อกซ์เล็ก ๆ น้อย ๆ ให้เล่น: http://jsfiddle.net/UtzND/


4
เยี่ยมมาก ... ฉันแค่คิดกับตัวเองว่า "อาจจะเกิดเหตุการณ์ที่เรียกว่า jQuery ไม่มีข้อมูลตำแหน่งเมาส์"! w00t!
Kasapo

2
สิ่งนี้สามารถเอาชนะได้ในเบราว์เซอร์ที่รองรับ createEvent jsfiddle.net/UtzND/26
Joe Enzminger

2
@JoeEnzminger ใช่ แต่ทำไมคุณถึงพ่ายแพ้สคริปต์ของตัวเองเพื่อพูด ... ?
OZZIE

3
ฉันกังวลเกี่ยวกับสคริปต์ของบุคคลที่สามที่สร้างเหตุการณ์การคลิกและสคริปต์ของฉันจัดการกับเหตุการณ์นี้โดยสันนิษฐานว่าเป็นสิ่งที่ผู้ใช้สร้างขึ้น (การคลิกจริง)
Joe Enzminger

2
@JoeEnzminger: การเดิมพันทั้งหมดจะปิดลงเมื่อรหัสของคุณอยู่ในเบราว์เซอร์ไม่มีอะไรที่คุณสามารถทำได้ที่ไม่สามารถเอาชนะคนที่ฉลาดเพียงพอได้ ฉันคิดว่าสิ่งที่ดีที่สุดที่คุณทำได้คือตรวจสอบสิ่งต่างๆมากมาย: มีoriginalEventหรือไม่? มันเป็นสิ่งที่ถูกต้องหรือไม่? มีพิกัดที่ไหนไหม พิกัดสอดคล้องกันหรือไม่ พิกัดข้างใน#fooหรือเปล่า ...
สั้นเกินไป

44

คุณสามารถใช้พารามิเตอร์เพิ่มเติมตามที่ระบุไว้ในคู่มือทริกเกอร์ jQuery :

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

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

3
ปัญหาเดียวที่ฉันเห็นด้วยกับเรื่องนี้คือการที่คุณไม่สามารถแยกแยะความแตกต่างระหว่างการคลิกปกติและ$x.click()การ.click()โทรมีอย่างชัดเจนบอกคุณว่าพวกเขากำลังแกล้งมัน นี่อาจเป็นหรือไม่เป็นปัญหาขึ้นอยู่กับสิ่งที่ Kevin Owocki กำลังทำอยู่
สั้นเกินไป

1
@mu: ฉันไม่ค่อยเข้าใจความแตกต่างของคุณระหว่างการคลิก "ปกติ" (ผู้ใช้?) กับ$x.click()ซึ่งเป็น eventHandler (สำหรับการคลิกของผู้ใช้ซึ่งอาจเป็น "ปกติ")
Shikiryu

1
ความแตกต่างคือหนึ่งมาจากผู้ใช้ แต่อีกคนมาจากซอฟต์แวร์ คลิกปลอมอาจมาจากปลั๊กอินหรือโค้ดอื่น ๆ ที่ไม่สามารถแก้ไขเพื่อเพิ่มอาร์กิวเมนต์พิเศษได้ ฉันไม่ได้วิจารณ์วิธีแก้ปัญหาของคุณเพียงแค่สังเกตช่องโหว่ที่เป็นไปได้
สั้นเกินไป

แม้ว่า mu จะถูกต้องและจะใช้ไม่ได้ในทุกสถานการณ์ แต่ก็เป็นสิ่งที่ฉันกำลังมองหาอยู่ขอบคุณ! ไม่ทราบว่าฉันสามารถส่งผ่านพารามิเตอร์พิเศษเช่น var ได้ แต่นั่นคือสิ่งที่ฉันต้องการในการทดสอบการคลิก "จริง" ใน UI ที่ซับซ้อนซึ่งถือว่าการคลิก "จริง" บางส่วนเป็นแบบโปรแกรม ขอบคุณสำหรับโซลูชันที่มีประโยชน์อย่างไม่น่าเชื่อทั้งสอง!
ฟิล

9

มีคำถามอื่นตอบไปแล้ว

จะตรวจสอบได้อย่างไรว่า click () เป็นการคลิกเมาส์หรือถูกเรียกโดยรหัสบางอย่าง?

ใช้whichคุณสมบัติของวัตถุเหตุการณ์ ควรเป็นundefinedเหตุการณ์ที่เรียกใช้รหัส

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

ตัวอย่าง JsFiddle - http://jsfiddle.net/interdream/frw8j/

หวังว่าจะช่วยได้!


2
ไม่ได้ผลเสมอไป เช่นselectจะให้e.which==undefinedแม้กระทั่งสำหรับเหตุการณ์ที่แท้จริง
JNF

5

ฉันได้ลองวิธีแก้ปัญหาข้างต้นทั้งหมดแล้วไม่มีอะไรได้ผลในกรณีของฉัน โซลูชันด้านล่างใช้ได้ผลสำหรับฉัน หวังว่ามันจะช่วยคุณได้เช่นกัน

$(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 ระดับ 3 ระบุ event.isTrusted ขณะนี้รองรับเฉพาะใน IE9 + และ Firefox เท่านั้น (จากการทดสอบของฉันฉันยังอ่าน (แม้ว่าจะไม่ได้รับการวิจัยอย่างละเอียด) ว่าสามารถแทนที่ได้ในบางเบราว์เซอร์และอาจยังไม่พร้อมที่จะเชื่อถือได้ 100% (น่าเสียดาย)

นี่คือ fiddle ของ @ mu รุ่นแก้ไขที่ใช้งานได้บน IE และ Firefox


จุดดี. ฉันไม่คิดว่าอะไรจะมั่นคง 100% แม้ว่า คุณต้องผสมในการทดสอบบางอย่างเพื่อดูว่าisTrustedรองรับและเขียนไม่ได้ ฉันคิดว่าคำตอบที่แท้จริงขึ้นอยู่กับสาเหตุที่อยู่เบื้องหลังคำถามนี้และเราไม่เคยพบสาเหตุ
สั้นเกินไป

@mu ฉันมาถึงคำถามนี้หลังจากถามคำถามที่คล้ายกัน แต่ทั่วไปมากกว่า กรณี "ทำไม" ของฉันคือฉันต้องการตรวจสอบให้แน่ใจว่าฉันดำเนินการเพียงอย่างเดียว (ธุรกรรมทางการเงินแม้ว่าจะเป็นเพียงเล็กน้อยก็ตาม) หากผู้ใช้ดำเนินการยืนยันโดยตรงบนเพจ
Joe Enzminger

1

โซลูชัน Vanila js:

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

-1

จะไม่เข้าร่วมในการอภิปรายทางปัญญารหัสที่ใช้สำหรับฉันในการกรอง.click()และ.trigger('click')เป็น -

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