Ich habe ein Skript erstellt, das beim Mouseover in einem übergeordneten Container aktiviert wird und dessen untergeordnete Elemente von der Maus entfernen soll. Ich habe es derzeit zum Laufen gebracht, aber es gibt einige Teile des Codes, die zu widersprechen scheinen, wie REACT-Code aussehen sollte. Besonders zwei Teile.
Ich verwende einen Zähler in der Renderfunktion, damit jeder Bereich seine korrekte benutzerdefinierte Eigenschaft erhält. Dabei handelt es sich
state.customProperties
um ein Array, das die benutzerdefinierten Eigenschaften beim Mouseover des übergeordneten Elements aktualisiert.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> ); }
In der Mausbewegungsfunktion verwende ich
document.getElementById
undquerySelectorAll
um alle Abschnittselemente abzurufen und die Mauskoordinaten von der Maus mit den Abschnittselementkoordinaten zu vergleichen.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 }); }
Ich habe das Gefühl, dass ich das alles falsch mache. Ich bin nicht sicher, wie ich den Zähler vermeiden könnte, während ich eine generische returnCustomProp
Funktion behalte , um die Eigenschaften für dieses Element zurückzugeben (im Live-Code habe ich ungefähr 200 dieser Elemente, so dass das manuelle Festlegen der Array-Elementnummer für sie nicht effizient ist). .
Der zweite Teil fühlt sich hackig an, ein Element anhand seiner ID anzuvisieren, die sich innerhalb der eigentlichen Komponente befindet. Ich habe das Gefühl, ich sollte in der Lage sein, dies zu erreichen, ohne das DOM zu durchqueren. Das Verweisen auf die Abschnittselemente könnte eine Lösung sein, aber ich glaube, Verweise sollten auf ein Minimum beschränkt werden, und wie bereits erwähnt, besteht der eigentliche Code aus Hunderten dieser Abschnitte.
Der Code macht nicht viel mehr atm als die custom="customProperty(0 0)"
Eigenschaft zu aktualisieren . Sie können dies durch den Elementinspektor beim Mouseover sehen.
Kann ich diese Funktion zum <section>
Funktionieren bringen, ohne die Elemente innerhalb der Renderfunktion zählen zu müssen und ohne sie verwenden zu müssen document.querySelectorAll
?
this.parentContainer
Habe übrigens einen Fehler , solltethis.ParentContainer
groß geschrieben werden). Irgendwelche Gedanken darüber, wie ich umgehen kann, wenn ichlet counter
die Funktion zum Rendern innerhalb des Renderings verwenden muss?sections
. Ich möchte die Funktion generisch halten. Aus der Frage:(in the live code I've got about 200 of these elements so setting the array item number for them manually is not efficient).
Vielleicht ist das Zählen innerhalb der Renderfunktion doch der effizienteste Weg.Sie sollten DOM nicht direkt manipulieren, da der Prozess auf dem virtuellen Dom reagiert. Laut React doc sollten Sie die Ref-Weiterleitung verwenden. Für weitere Informationen lesen Sie bitte diese .
quelle
Sie können die Methode
findDOMNode()
von ReactDOM verwenden, wenn Sie keine andere Lösung finden, als in der Dokumentation angegeben:findDOMNode
ist eine Escape-Luke, die für den Zugriff auf den zugrunde liegenden DOM-Knoten verwendet wird. In den meisten Fällen wird von der Verwendung dieser Notluke abgeraten, da sie die Komponentenabstraktion durchdringt.Als Beispiel möchte ich einen Anwendungsfall meiner App freigeben, in dem ich den Verweis auf den Container DOM div benötige, um das Drag & Drop für die von mir verwendeten Bibliotheken zu implementieren.
Beispiel:
quelle