2016-01-21 10 views
6

jsfiddle: https://jsfiddle.net/leiming/5e6rtgwd/onFocus bańka w React

class Sample extends React.Component { 
 

 
    onInputFocus(event) { 
 
    console.log('react input focus') 
 
    } 
 

 
    onSpanFocus(event) { 
 
    console.log('react span focus') 
 
     // event.stopPropagation() 
 
    } 
 

 
    render() { 
 
    return (<span onFocus = {this.onSpanFocus}> 
 
     react input: <input type="text" 
 
     onFocus = {this.onInputFocus} /> 
 
     </span>) 
 
    } 
 
} 
 

 
ReactDOM.render(< Sample/> , 
 
    document.getElementById('container') 
 
);
<div id="container"> 
 
    <!-- This element's contents will be replaced with your component. --> 
 
</div> 
 

 
<div> 
 
    <span onfocus="(function(){console.log('normal span')})()"> 
 
    normal input:<input type="text" onfocus="(function(){console.log('normal input focus')})()"> 
 
</span> 
 
</div>

jsfiddle: https://jsfiddle.net/leiming/5e6rtgwd/

Korzystanie zareagować, onFocus w <input/> woli bańki, która nie jest taka sama jak zwykle HTML5.

Czy ktokolwiek mógłby mi podać dokument referencyjny, dlaczego skupić się na bąblach z React?

+1

Pracują nad tym: https://github.com/facebook/react/issues/6410 – velop

Odpowiedz

12

focus wydarzeń do not bubble, więc masz rację, że zachowanie w React różni się od zachowania w DOM. DOM ma zdarzenie focusinthat 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 focusz 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.

+0

Dzięki, jasne wyjaśnienie –

+0

Dobre wyjaśnienie i naprawdę wkładasz wysiłek w zrozumienie, a następnie wyjaśnienie informacji w sposób jasny droga. – alexrussell

Powiązane problemy