Sprawdź, czy zdarzenie jest wywoływane przez człowieka

140

Mam moduł obsługi dołączony do zdarzenia i chciałbym, aby był wykonywany tylko wtedy, gdy jest wyzwalany przez człowieka, a nie przez metodę trigger (). Jak odróżnić różnicę?

Na przykład,

$('.checkbox').change(function(e){
  if (e.isHuman())
  {
    alert ('human');
  }
});

$('.checkbox').trigger('change'); //doesn't alert
Dziamid
źródło

Odpowiedzi:

212

Możesz sprawdzić e.originalEvent: jeśli jest zdefiniowane, kliknięcie jest ludzkie:

Spójrz na skrzypce http://jsfiddle.net/Uf8Wv/

$('.checkbox').change(function(e){
  if (e.originalEvent !== undefined)
  {
    alert ('human');
  }
});

mój przykład na skrzypcach:

<input type='checkbox' id='try' >try
<button id='click'>Click</button>

$("#try").click(function(event) {
    if (event.originalEvent === undefined) {
        alert('not human')
    } else {
        alert(' human');
    }


});

$('#click').click(function(event) {
    $("#try").click();
});
Nicola Peluchetti
źródło
1
@Nicola Czy to jest gdzieś udokumentowane?
Šime Vidas,
@ Czasem nie wiem, ale myślę, że to standard. spójrz tutaj: api.jquery.com/category/events/event-object
Nicola Peluchetti
@Nicola Widzę, to jest jQuery. jQuery przechowuje oryginalny obiekt zdarzenia wewnątrz tej właściwości. Przy okazji, co masz na myśli mówiąc, że nie wiesz? Właśnie podałeś link do dokumentacji:)
Šime Vidas
1
Wygląda na to, że możesz również użyćevent.isTrigger
avoliva
1
@Anurag, właśnie miałem ten sam problem. Wygląda na to, że jQuery zapełnia się, originalEventgdy zdarzenie jest wyzwalane przez DOM.click(), ale możesz użyć $($("#try")[0]).click();, co jest niezgrabne, ale działa.
Daniel Garrett,
19

Bardziej proste niż powyżej byłoby:

$('.checkbox').change(function(e){
  if (e.isTrigger)
  {
    alert ('not a human');
  }
});

$('.checkbox').trigger('change'); //doesn't alert
Kenneth Spencer
źródło
To najlepsza odpowiedź. Aby uzyskać wyjaśnienie, zobacz: stackoverflow.com/questions/10704168/…
jaredjacobs
3
Chociaż jest to kuszące i prawdopodobnie przytulne w praktyce, zwróć uwagę, że programiści jQuery nie chcą od tego czasu przechodzić isTriggerdo publicznego interfejsu API .
Jon
7

Myślę, że jedynym sposobem na to byłoby przekazanie dodatkowego parametru w triggerwywołaniu zgodnie z dokumentacją .

$('.checkbox').change(function(e, isTriggered){
  if (!isTriggered)
  {
    alert ('human');
  }
});

$('.checkbox').trigger('change', [true]); //doesn't alert

Przykład: http://jsfiddle.net/wG2KY/

detaylor
źródło
1
możesz sprawdzić właściwość originalEvent obiektu zdarzenia: jeśli zdarzenie nie pochodzi z kliknięcia, jest nieokreślone
Nicola Peluchetti
1
Z jakiegoś powodu zdarzenie event.originalEvent nie działało dla mnie (po prostu wróciło 1) podczas używania modułu obsługi „kliknięcia” Zepto. Wypróbowałem więc powyższe rozwiązanie. Działał jak urok.
Larrydx
7

Zaakceptowana odpowiedź nie działa dla mnie. Minęło 6 lat i od tego czasu jQuery bardzo się zmienił.

Na przykład event.originalEventzawsze zwracatrue z jQuery 1.9.x. Mam na myśli, że przedmiot zawsze istnieje, ale treść jest inna.

Ci, którzy używają nowszych wersji jQuery, mogą wypróbować tę. Działa na Chrome, Edge, IE, Opera, FF

if ((event.originalEvent.isTrusted === true && event.originalEvent.isPrimary === undefined) || event.originalEvent.isPrimary === true) {
    //Hey hooman it is you
}
Ergec
źródło
3

Obecnie większość przeglądarek obsługuje event.isTrusted :

if (e.isTrusted) {
  /* The event is trusted: event was generated by a user action */
} else {
  /* The event is not trusted */
}

Z dokumentów :

IsTrusted tylko do odczytu własność Eventinterfejs jest Boolean to prawdą , gdy zdarzenie zostało wygenerowane przez działanie użytkownika, a fałszywe , gdy zdarzenie zostało utworzone lub zmodyfikowane przez skrypt lub wysyłane poprzez EventTarget.dispatchEvent () .

felipsmartins
źródło
0

Możesz użyć onmousedown, aby wykryć kliknięcie myszą w porównaniu z wywołaniem trigger ().

boateng
źródło
Mogę nie pracować w następującym scenariuszu: Czasami można wybrać elementy strony za pomocą klawisza Tab. Na przykład, jeśli zaznaczyłem w ten sposób pole wyboru, mogę zaznaczyć / odznaczyć za pomocą klawisza spacji. Lub nawet otwórz drodpdown za pomocą klawisza strzałki w dół.
Diego Favero
0

Pomyślałbym o możliwości, w której sprawdzasz pozycję myszy, na przykład:

  • Kliknij
  • Uzyskaj pozycję myszy
  • Nakłada się na współrzędne przycisku
  • ...
Łukasz
źródło
Mogę nie pracować w następującym scenariuszu: Czasami można wybrać elementy strony za pomocą klawisza Tab. Na przykład, jeśli zaznaczyłem w ten sposób pole wyboru, mogę zaznaczyć / odznaczyć za pomocą klawisza spacji. Lub nawet otwórz drodpdown za pomocą klawisza strzałki w dół.
Diego Favero
0

O ile masz kontrolę nad całym swoim kodem, nie ma połączeń obcych $(input).focus()niż setFocus().

Użycie zmiennej globalnej jest dla mnie poprawnym sposobem.

var globalIsHuman = true;

$('input').on('focus', function (){
    if(globalIsHuman){
        console.log('hello human, come and give me a hug');
    }else{
        console.log('alien, get away, i hate you..');
    }
    globalIsHuman = true;
});

// alien set focus
function setFocus(){
    globalIsHuman = false;
    $('input').focus();
}
// human use mouse, finger, foot... whatever to touch the input

Jeśli jakiś kosmita nadal chce zadzwonić $(input).focus()z innej planety. Powodzenia lub sprawdź inne odpowiedzi

vanduc1102
źródło
Zapobiega to tylko dzwonieniu setFocus()- nie przeszkadza ludziom w wywołaniu zdarzenia fokusu. Brak pisania setFocus()w ogóle uniemożliwiłby ludziom nazywanie tego, więc nie widzę korzyści. W rzeczywistości ludzie nadal mogliby dzwonić $('input').focus()i sprawić, by przeszło.
Rob
wow, po raz pierwszy mam komuś komentarz zaraz po tym, jak odpowiem na pytanie, zaktualizuję odpowiedź
vanduc1102
Jeśli pracujesz w zamkniętym środowisku bez skryptów innych firm / osób trzecich, działałoby to w idealnym świecie. Jednak większość praktycznych aplikacji jest przeznaczona dla witryn klienckich, do których dodano wszelkiego rodzaju wtyczki i skrypty, które bardzo dobrze mogą wywołać ten fokus. Jedyną rzeczą, która może w tym pomóc, jest zawinięcie kodu (i każdego kodu, który musi wywołać tę funkcję) w funkcję o określonym zakresie, taką jak ta: (function(){/*your code here*/})();Dzięki temu funkcja setFocus będzie bezpieczna przed wywołaniem, a wartość logiczna nie zostanie zmieniona przez zewnętrzne skrypty.
Xandor