focus
wydarzeń do not bubble, więc masz rację, że zachowanie w React różni się od zachowania w DOM. DOM ma zdarzenie focusin
that does bubble; oto demonstracji:
<div>
<span onfocus="(function(){console.log('span focus')})()">
onfocus: <input type="text"
onfocus="(function(){console.log('input focus')})()">
</span>
</div>
<div>
<span onfocusin="(function(){console.log('span focusin')})()">
onfocusin: <input type="text"
onfocusin="(function(){console.log('input focusin')})()">
</span>
</div>
Przeglądając the React source code, wydaje się to było zamierzone; kod sprawdza, czy przeglądarka obsługuje zdarzenie focus
z przechwytywaniem, i implementuje je poprzez zdarzenie focus
z ReactEventListener.trapCapturedEvent
zamiast ReactEventListener.trapBubbledEvent
. Jest to konieczne, ponieważ React implementuje swój syntetyczny system zdarzeń za pomocą delegowania zdarzeń, a zatem musi wykorzystywać przechwytywanie lub propagację w celu obsługi wszystkich zdarzeń. The article linked to in the comment objaśnia, jak to działa:
Problem polega na tym, że te zdarzenia się nie pojawiają. Zdarzenie fokusu lub rozmycia na łączu jest uruchamiane tylko w samym łączu, a nie w żadnym elementu nadrzędnym łącza.
To starożytna zasada. Kilka zdarzeń, w szczególności fokus, rozmycie i zmiana, nie bańka drzewa dokumentu. Dokładne przyczyny tego zostały utracone w mgle historii, ale częściowo przyczyną jest to, że te wydarzenia po prostu nie mają sensu w niektórych elementach. Użytkownik nie może w żaden sposób skupić się na lub zmienić losowego akapitu i dlatego te zdarzenia nie są dostępne w tych elementach HTML. Ponadto nie spekulują.
...
Z wyjątkiem sytuacji, gdy korzystasz z funkcji przechwytywania zdarzeń.
...
Jednym z najciekawszych wniosków z moich badań zdarzeń jest to, że podczas definiowania obsługi zdarzeń w fazie przechwytywania przeglądarka wykonuje dowolny i wszystkie programy obsługi zdarzeń określonych na przodków celu zdarzenia stwierdzi, czy dane wydarzenie ma sens w odniesieniu do tych elementów lub nie.
Wydaje się całkiem prawdopodobne, że zespół React postanowiliśmy po prostu zrobić imprezę zawsze bubble (które, szczerze mówiąc, jest to, czego oczekuje się od specyfikacji DOM jak dobrze dopóki nie przeczytałem swoje pytanie). Implementacje przeglądarki nie wydają się być spójne; one issue comment wspomina, że w Firefoksie pojawiają się bańki o numerach focus
, ale nie udało mi się odtworzyć tego w najnowszej wersji. Jednak użycie atrybutu onfocusin
lub użycie addEventListener("focusin", ...)
również nie działało w FF. Możliwe, że była to po prostu próba normalizacji zdarzeń w różnych przeglądarkach.
Wszystko, co powiedział, to wydaje się, że to chyba błąd, gdzie własność .bubbles
na SyntheticFocusEvent
jest false
zamiast true
.
Pracują nad tym: https://github.com/facebook/react/issues/6410 – velop