Zastanawiałam się, czy event.preventDefault()
i return false
były takie same.
Zrobiłem kilka testów i wygląda na to
Jeśli na przykład program obsługi zdarzeń zostanie dodany przy użyciu starego modelu
elem.onclick = function(){ return false; };
Następnie
return false
zapobiega domyślnej akcji, takiej jakevent.preventDefault()
.Jeśli program obsługi zdarzeń zostanie dodany przy użyciu
addEventListener
, na przykładelem.addEventListener( 'click', function(e){ return false; }, false );
Wtedy
return false
nie zapobiega domyślnej akcji.
Czy wszystkie przeglądarki zachowują się w ten sposób?
Czy jest więcej różnic między event.preventDefault()
i return false
?
Gdzie mogę znaleźć dokumentację (której nie mogłem w MDN) na temat return false
zachowania się event.preventDefault()
w niektórych przypadkach?
Moje pytanie dotyczy tylko zwykłego javascript, a nie jQuery, więc proszę nie oznaczać go jako duplikatu zdarzenia event.preventDefault () vs. return false , nawet jeśli oba pytania mają prawie ten sam tytuł.
return false
zachowuje się inaczej niż zwykły JavaScript. Co więcej, na drugie pytanie nie ma odpowiedzi wyjaśniającej różnicę w zwykłym JS (jest tylko komentarz, który to wyjaśnia, ale jest trudny do znalezienia). Myślę więc, że lepiej mieć dwa różne pytania.Odpowiedzi:
Object model Wydarzenia Specyfikacja W3C Dokument w 1.3.1. Interfejsy rejestracji zdarzeń stwierdzają, że
handleEvent
w EventListener nie ma zwracanej wartości:pod 1.2.4. Anulowanie zdarzenia dokument również to stwierdza
co powinno zniechęcać Cię do używania jakiegokolwiek efektu, jaki może mieć zwrócenie wartości prawda / fałsz w dowolnej przeglądarce i użyciu
event.preventDefault()
.Aktualizacja
Specyfikacja HTML5 w rzeczywistości określa sposób traktowania wartości zwracanej inaczej. Sekcja 7.1.5.1 specyfikacji HTML stwierdza, że
za wszystko oprócz zdarzenia „mouseover”.
Wniosek
Nadal zalecałbym używanie
event.preventDefault()
w większości projektów, ponieważ będziesz kompatybilny ze starą specyfikacją, a tym samym ze starszymi przeglądarkami. Tylko jeśli potrzebujesz tylko obsługi najnowocześniejszych przeglądarek, zwracanie wartości false w celu anulowania jest w porządku.źródło
stopPropagation()
,preventDefault()
orazreturn false
: jsfiddle.net/m1L6of9x . W nowoczesnych przeglądarkach te dwie ostatnie zachowują się tak samo.Oto kilka przykładów, które mogą pomóc ludziom lepiej zrozumieć i rozwiązywać problemy.
TL; DR
on*
procedury obsługi zdarzeń (np.onclick
atrybut w elemencie przycisku): zwraca false, aby anulować zdarzenieaddEventListener
jest innym API, wartości zwracane (np.false
) są ignorowane: użyjevent.preventDefault()
.onclick="<somejs>"
ma swoje własne potencjalne zamieszanie, ponieważ<somejs>
jest zawarty w treści funkcji onclick.getEventListeners
interfejsu API przeglądarki devtools, aby zobaczyć, jak wygląda Twój detektor zdarzeń, aby rozwiązać problem, jeśli program obsługi zdarzeń nie działa zgodnie z oczekiwaniami.Przykład
Ten przykład jest specyficzny dla
click
zdarzenia z<a>
łączem ... ale można go uogólnić dla większości typów zdarzeń.Mamy kotwicę (link) z klasą
js-some-link-hook
, którą chcemy otworzyć modalnie i uniemożliwić nawigację po stronie.Poniższe przykłady zostały uruchomione w Google Chrome (71) na MacOS Mojave.
Jedną z głównych pułapek jest założenie, że
onclick=functionName
jest to takie samo zachowanie, jak używanieaddEventListener
Powiedzmy, że mamy znacznik kotwicy (link), który chcemy obsługiwać za pomocą javascript, gdy javascript jest włączony. Nie chcemy, aby przeglądarka podążała za linkiem po kliknięciu („zapobiegaj domyślnemu” zachowaniu).
<a href="https://www.example.com/url/to/go/to/when/no/javascript" class="js-some-link-hook">click me!</a>
atrybut onclick
function eventHandler (event) { // want to prevent link navigation alert('eventHandler ran'); return false; } function addEventListenerToElement () { var link = document.querySelector('.js-some-link-hook'); link.setAttribute('onclick', eventHandler); } addEventListenerToElement();
Następnie uruchom w konsoli devtools przeglądarki:
var el = document.querySelector('a.js-some-link-hook'), listener = getEventListeners(el).click[0].listener; console.log(''+listener); // to avoid truncation of output
... i widzisz:
function onclick(event) { function eventHandler (event) {alert('eventHandler ran'); return false;} }
To w ogóle nie działa. Podczas korzystania
onclick=
z funkcji obsługi funkcja jest opakowana w inną funkcję.Możesz zobaczyć, że moja definicja funkcji jest dołączona, ale nie została wywołana, ponieważ określiłem odwołanie do funkcji bez wywoływania go. czyli musimy
onclick="functionName()"
nieonclick="functionName"
upewnić się,functionName
jest uruchamiany, gdy element zostanie kliknięty.Dalej widać, że nawet jeśli moja funkcja została wywołana, a moja funkcja zwróciłaby fałsz ...
onclick
funkcja nie zwróciłaby tej fałszywej wartości ... która jest wymagana do „anulowania” zdarzenia.W celu ustalenia tego, możemy ustawić
onclick
sięreturn myHandlerFunc();
co gwarantuje, żeonclick
zwraca wartość return (false) zmyHandlerFunc
.Możesz również usunąć
return false;
frommyHandlerFunc
i zmienić naonclick
be,myHandlerFunc(); return false;
ale ma to mniej sensu, ponieważ prawdopodobnie chcesz zachować razem logikę w funkcji obsługi.Zauważ, że podczas ustawiania za
onclick
pomocą javascript , gdy ustawiaszonclick
bezpośrednio w html, a nie w javascript (jak moje przykłady),onclick
wartość atrybutu to string i wszystko działa. Jeśli ustawiaszonclick
za pomocą JavaScript, musisz zwrócić uwagę na typ. Jeśli powiesz, żeelement.setAttribute('onclick', myHandlerFunc())
myHandlerFunc
zostanie uruchomiony teraz, a wynik zostanie zapisany w atrybucie ... zamiast być uruchamiany po każdym kliknięciu. Zamiast tego powinieneś upewnić się, że wartość atrybutu jest ustawiona jako ciąg.element.setAttribute('onclick', 'return myHandlerFunc();')
Teraz, gdy widzimy, jak to działa, możemy zmodyfikować kod, aby robił, co chcemy. Dziwny przykład dla celów ilustracyjnych (nie używaj tego kodu):
function eventHandler (e) { // want to prevent link navigation alert('eventHandler ran'); console.log(e); return false; } function addEventListenerToElement () { var link = document.querySelector('.js-some-link-hook'); link.setAttribute('onclick', 'return ('+eventHandler+')(event);'); } addEventListenerToElement();
Widzisz, opakowaliśmy naszą definicję funkcji eventHandler w łańcuch. W szczególności: samowykonująca się funkcja z instrukcją return na początku.
Ponownie w konsoli Chrome Devtools:
var el = document.querySelector('a.js-some-link-hook'), listener = getEventListeners(el).click[0].listener; console.log(''+listener); // to avoid truncation of output
...przedstawia:
function onclick(event) { return (function eventHandler (e) { // want to prevent link navigation alert('eventHandler ran'); console.log(e); return false; })(event); }
... więc tak, to powinno działać. Oczywiście, jeśli klikniemy link, otrzymamy alert i odrzucimy alert, strona nie będzie nigdzie nawigować ani odświeżać.
Jeszcze jedna uwaga na temat
onclick
... Jeśli chcesz otrzymać i wykorzystaćevent
parametr w momencie zdarzenia, powinieneś zauważyć, że nazywa się on „zdarzenie”. Możesz uzyskać do tego dostęp w swoim programie obsługi za pomocą nazwyevent
(dostępne wonclick
zakresie funkcji nadrzędnej ). Możesz też skonstruować procedurę obsługi tak, aby przyjmowałaevent
jako parametr (lepsze do testowania) ... np.onclick="return myEventHandler(event);"
Lub jak widać w poprzednim przykładzie.addEventListener
function eventHandler (ev) { // want to prevent link navigation alert('eventHandler ran'); console.log(ev); return false; } function addEventListenerToElement () { var link = document.querySelector('.js-some-link-hook'); link.addEventListener('click', eventHandler, false); } addEventListenerToElement();
devtools przeglądarki:
var el = document.querySelector('a.js-some-link-hook'), listener = getEventListeners(el).click[0].listener; console.log(''+listener); // to avoid truncation of output
wynik:
function eventHandler (ev) { // want to prevent link navigation alert('eventHandler ran'); console.log(ev); return false; }
Więc już widać różnicę. Nie
addEventListener
jesteśmy opakowani wonclick
funkcję. Nasz program obsługi otrzymujeevent
parametr bezpośrednio (więc możemy go nazwać, jak chcemy). Również naszreturn false
jest tutaj na „najwyższym poziomie” i nie musimy się martwić o dodanie dodatkowej instrukcji zwrotu, jak w przypadkuonclick
.Więc wygląda na to, że powinno działać. Klikając w link otrzymujemy alert. Odrzuć alert, a strona przejdzie / odświeży się. tj. zdarzenie NIE zostało anulowane przez zwrócenie wartości false.
Jeśli sprawdzimy specyfikację (zobacz zasoby na dole), zobaczymy, że nasza funkcja wywołania zwrotnego / obsługi dla addEventListener nie obsługuje typu zwracanego. Możemy zwrócić, co chcemy, ale ponieważ nie jest to część interfejsu API / interfejsu przeglądarki, nie ma to żadnego efektu.
Rozwiązanie: używanie
event.preventDefault()
zamiastreturn false;
...function eventHandler (ev) { // want to prevent link navigation ev.preventDefault(); alert('eventHandler ran'); } function addEventListenerToElement () { var link = document.querySelector('.js-some-link-hook'); link.addEventListener('click', eventHandler, false); } addEventListenerToElement();
devtools przeglądarki ...
var el = document.querySelector('a.js-some-link-hook'), listener = getEventListeners(el).click[0].listener; console.log(''+listener); // to avoid truncation of output
daje ...
function eventHandler (ev) { // want to prevent link navigation ev.preventDefault(); alert('eventHandler ran'); }
...zgodnie z oczekiwaniami.
Testowanie ponownie:
Więc z
addEventListener
użyciemevent.preventDefault()
jako zwracanie fałszu nic nie robi.Zasoby
Specyfikacja HTML5 ( https://www.w3.org/TR/html5/webappapis.html#events ) myli rzeczy, ponieważ używają obu
onclick
iaddEventListener
w swoich przykładach i mówią, co następuje:Wydaje się więc sugerować, że
return false
anuluje wydarzenie zarówno dla, jakaddEventListener
ionclick
.Ale jeśli spojrzysz na ich połączoną definicję
event-handler
ciebie, zobaczysz:https://www.w3.org/TR/html5/webappapis.html#event-handler
Wydaje się więc, że
return false
anulowanie zdarzenia naprawdę dotyczy tylkoonclick
(lub ogólnieon*
) programów obsługi zdarzeń, a nie programów obsługi zdarzeń zarejestrowanych za pośrednictwemaddEventListener
innego interfejsu API.Ponieważ
addEventListener
interfejs API nie jest objęty specyfikacją html5 (tylkoon*
procedury obsługi zdarzeń) ... byłoby mniej zagmatwane, gdyby trzymali sięon*
obsługi zdarzeń stylu w swoich przykładach.źródło
Różnica między allowDefault, stopPropogation, return false
Akcja domyślna - akcja po stronie serwera po wywołaniu zdarzenia sterowania.
Załóżmy, że mamy kontrolkę DIV i wewnątrz niej znajduje się przycisk. Zatem div jest nadrzędną kontrolą przycisku. Mamy kliknięcie po stronie klienta i zdarzenie kliknięcia przycisku po stronie serwera. Mamy również zdarzenie kliknięcia div po stronie klienta.
W przypadku kliknięcia przycisku po stronie klienta możemy kontrolować działania kontroli rodzicielskiej i kodu po stronie serwera na trzy sposoby:
return false
- To zezwala tylko na zdarzenie kontroli po stronie klienta. Zdarzenie po stronie serwera i zdarzenie po stronie klienta formantu nadrzędnego nie jest wyzwalane.preventDefault()
- Pozwala to na zdarzenie kontroli po stronie klienta i kontrolę nadrzędną. Zdarzenie po stronie serwera, tj. Domyślna akcja formantu nie jest uruchamiana.stopPropogation()
- Pozwala to na zdarzenie kontroli po stronie klienta oraz po stronie serwera. Zdarzenie po stronie klienta dotyczące formantu nie jest dozwolone.źródło
return false
nie zatrzymujesz propagacji, więc uruchamiana jest kontrola rodzicielska ( wersja demonstracyjna ). Co więcej, nie jestem pewien, co masz na myśli mówiąc o „ zdarzeniu kliknięcia po stronie serwera ”.return false
jest tylko dla IE,event.preventDefault()
jest obsługiwany przez chrome, ff ... nowoczesne przeglądarkiźródło
return false
działa tak, jakevent.preventDefault()
wtedy, gdy program obsługi zdarzeń jest dodawany przy użyciu starego modelu