tag property page for javascript html html5 reactjs dom-events

javascript - page - title property html



Reaccionar y desenfocar evento (2)

Tengo un problema simple con React y manejo de eventos. Mi componente se parece a esto (básicamente una tabla):

const MyList = ({ items, onBlur }) => <table onBlur={onBlur}}> <thead> <tr> <th>ID</th> <th>Title</th> <th>Publisher</th> <th>Year</th> <th>Author</th> <th>System</th> <th/> </tr> </thead> <tbody> {items.map(item => <MyListRow key={item.Id} item={item}/>)} </tbody> </table>;

Quiero que el evento de blur se dispare solo si el enfoque se sale de la mesa . En su lugar, el evento se activa en cada elemento secundario de la tabla cuando pierde el foco.

De acuerdo con los documentos, React permite que los eventos de enfoque se desarrollen.

La pregunta es: ¿Cómo puedo hacer que mi método onBlur se onBlur solo cuando el foco se sale de la mesa? IOW: ¿Cómo puedo filtrar y descartar los eventos no deseados que rebosan para que solo revele los eventos que indican una pérdida de enfoque para la tabla?


El problema es que una tabla no tiene realmente un concepto de enfoque ya que no es una entrada en sí misma.

Cuando onBlur se active en las entradas contenidas, comprobaremos el relatedTarget del evento onBlur que se debe establecer en el elemento que tiene el foco RECEPTADO (o null ). Luego usamos una función que se parentNode hacia arriba a través de parentNode s desde ese elemento recién enfocado y nos asegurará de que el objetivo parentNode de nuestro evento (la tabla) no sea un antepasado del elemento enfocado recientemente. Si la condición pasa, se supone que la tabla ya no tiene ningún foco.

const focusInCurrentTarget = ({ relatedTarget, currentTarget }) => { if (relatedTarget === null) return false; var node = relatedTarget.parentNode; while (node !== null) { if (node === currentTarget) return true; node = node.parentNode; } return false; } const onBlur = (e) => { if (!focusInCurrentTarget(e)) { console.log(''table blurred''); } } const MyList = ({ items, onBlur }) => ( <table onBlur={onBlur}> <thead> <tr> <th>ID</th> <th>Title</th> <th>Publisher</th> <th>Year</th> <th>Author</th> <th>System</th> <th/> </tr> </thead> <tbody> <tr> <td>1</td> <td> <input type="text" /> </td> <td> <input type="text" /> </td> <td> <input type="text" /> </td> <td> <input type="text" /> </td> <td> <input type="text" /> </td> </tr> </tbody> </table> ); ReactDOM.render( <MyList onBlur={onBlur} />, document.getElementById(''root'') );

table { padding: 10px; border: 1px solid red; }

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="root"></div> <br /> <input type="text" />

Referencias:

ACTUALIZADO:

Se eliminó el uso de ReactDOM.findDOMNode


Sin funciones personalizadas y compatible con Internet Explorer , dado que node.contains y document.activeElement son compatibles desde Internet Explorer 5, esto funciona:

const onBlur = (e) => { if ( !e.currentTarget.contains( document.activeElement ) ) { console.log(''table blurred''); } }

  • El método Node.contains () devuelve un valor booleano que indica si un nodo es descendiente de un nodo determinado o no.
  • Document.activeElement devuelve el elemento enfocado actualmente, es decir, el elemento que obtendrá eventos de pulsación de tecla si el usuario escribe alguno.