Creé un script que se activa al pasar el mouse sobre un contenedor primario y debería alejar sus elementos secundarios del mouse. Actualmente lo tengo funcionando, pero hay algunas partes del código que parecen contradecir cómo debería ser el código REACT. Especialmente dos partes.
Estoy usando un contador en la función de representación para que cada intervalo obtenga su propiedad personalizada correcta, de la
state.customProperties
cual hay una matriz que actualiza las propiedades personalizadas al pasar el mouse del elemento principal.render() { let counter = 0; const returnCustomProp = function(that) { counter++; let x = 0; if (that.state.customProperties[counter - 1]) { x = that.state.customProperties[counter - 1].x; } let y = 0; if (that.state.customProperties[counter - 1]) { y = that.state.customProperties[counter - 1].y; } return "customProperty(" + x + " " + y + ")"; } return ( <div onMouseMove={this._testFunction} id="ParentContainer"> <section custom={returnCustomProp(this)}> <b>Custom content for part 1</b> <i>Could be way different from all the other elements</i> </section> <section custom={returnCustomProp(this)}> 2 </section> <section custom={returnCustomProp(this)}> <div> All content can differ internally so I'm unable to create a generic element and loop trough that </div> </section> <section custom={returnCustomProp(this)}> 4 </section> <section custom={returnCustomProp(this)}> 5 </section> <section custom={returnCustomProp(this)}> <div> <b> This is just test data, the actualy data has no divs nested inside secions </b> <h1> 6 </h1> </div> </section> <section custom={returnCustomProp(this)}> 7 </section> <section custom={returnCustomProp(this)}> 8 </section> </div> ); }
En la función mousemove que estoy usando
document.getElementById
yquerySelectorAll
para obtener todos los elementos de sección y comparar las coordenadas del mouse del mouse con las coordenadas de los elementos de sección.var mouseX = e.pageX; var mouseY = e.pageY; var spans = document.getElementById('ParentContainer').querySelectorAll('section'); var theRangeSquared = 10 * 10; var maxOffset = 5; var newCustomProperties = []; for (var i = 0; i < spans.length; i++) { var position = spans[i].getBoundingClientRect(); var widthMod = position.width / 2; var heightMod = position.height / 2; var coordX = position.x + widthMod; var coordY = position.y + heightMod + window.scrollY; // Distance from mouse var dx = coordX - mouseX; var dy = coordY - mouseY; var distanceSquared = (dx * dx + dy * dy); var tx = 0, ty = 0; if (distanceSquared < theRangeSquared && distanceSquared !== 0) { // Calculate shift scale (inverse of distance) var shift = maxOffset * (theRangeSquared - distanceSquared) / theRangeSquared; var distance = Math.sqrt(distanceSquared); tx = shift * dx / distance; ty = shift * dy / distance; } newCustomProperties.push({ x: tx, y: ty }); }
Tengo la sensación de que voy a hacer todo esto mal. No estoy seguro de cómo podría evitar el contador mientras mantengo una returnCustomProp
función genérica para devolver las propiedades de dicho elemento (en el código en vivo tengo alrededor de 200 de estos elementos, por lo que configurar el número de elemento de la matriz manualmente no es eficiente) .
La segunda parte se siente extraña al apuntar a un elemento por ID que está dentro del componente real. Siento que debería poder apuntar a esto sin atravesar el DOM. Hacer referencia a los elementos de la sección podría ser una solución, pero creo que las referencias deben mantenerse al mínimo y, como se indicó, el código real consta de cientos de estas secciones.
El código no hace mucho más cajero automático que actualizar la custom="customProperty(0 0)"
propiedad. Puede ver que esto sucede a través del inspector de elementos al pasar el mouse.
¿Puedo hacer que esta funcionalidad funcione sin tener que contar los <section>
elementos dentro de la función de renderizado y sin tener que usarla document.querySelectorAll
?
this.parentContainer
BTW, debe serthis.ParentContainer
capitalizado). ¿Alguna idea sobre cómo puedo evitar tener que usar ellet counter
interior de la función de renderizado?sections
. Me gustaría mantener la función genérica. De la pregunta:(in the live code I've got about 200 of these elements so setting the array item number for them manually is not efficient).
Quizás contar dentro de la función de renderizado es la forma más eficiente después de todo.No debe manipular DOM directamente porque reacciona el proceso en dom virtual. De acuerdo con el documento React, debes usar el reenvío de referencias. Para más detalles por favor lea esto .
fuente
Puede usar el método
findDOMNode()
de ReactDOM si no encuentra otra solución pero cómo dice la documentación:findDOMNode
es una trampilla de escape utilizada para acceder al nodo DOM subyacente. En la mayoría de los casos, se desaconseja el uso de esta trampilla de escape porque perfora la abstracción del componente.Como ejemplo, quiero compartir un caso de uso de mi aplicación donde necesito la referencia al contenedor DOM div para implementar el arrastrar y soltar para las bibliotecas que estaba usando.
Ejemplo:
fuente