Klick-Ereignis wird nicht ausgelöst, wenn Komponente in einem Schatten-DOM reagiert

8

Ich habe einen speziellen Fall, in dem ich eine React-Komponente mit einer Web-Komponente einkapseln muss. Das Setup scheint sehr geradlinig zu sein. Hier ist der React Code:

%Vor%

HTML:

%Vor%

Dies wird ordnungsgemäß geladen und das Klickereignis funktioniert. Wenn ich jetzt einen Webkomponenten-Wrapper für die React-Komponente erstellt habe, wird dieser korrekt gerendert, aber das Klickereignis funktioniert nicht. Hier ist mein Web Component Wrapper:

%Vor%

Und hier ist der HTML:

%Vor%

Gibt es etwas, das mir fehlt? Oder weigert sich React, in einer Webkomponente zu arbeiten? Ich habe eine Bibliothek wie Maple.JS gesehen, die so etwas macht, aber ihre Bibliothek funktioniert. Ich fühle mich, als würde ich eine kleine Sache vermissen.

Hier ist der CodePen, damit Sie das Problem sehen können:

Ссылка

    
josephnvu 16.06.2016, 17:57
quelle

4 Antworten

6

Es stellt sich heraus, dass das Shadow-DOM Klickereignisse neu tariert und die Ereignisse im Schatten einkapselt. React gefällt das nicht, da sie das Shadow-DOM nicht nativ unterstützen. Daher ist die Ereignisdelegierung deaktiviert und Ereignisse werden nicht ausgelöst.

Ich entschied mich, das Ereignis an den tatsächlichen Schattencontainer zu binden, der technisch "im Licht" ist. Ich verfolge das Aufsprudeln des Ereignisses mit event.path und feuere alle React Event-Handler im Kontext bis zum Shadow-Container.

Ich habe eine "retargetEvents" -Methode hinzugefügt, die alle möglichen Event-Typen an den Container bindet. Anschließend wird das richtige React-Ereignis durch Auffinden der "__reactInternalInstances" ausgelöst und der entsprechende Ereignishandler im Ereignisbereich / -pfad gesucht.

%Vor%

Ich würde die "retargetEvents" ausführen, wenn ich die React-Komponente in das Schatten-DOM rendere

%Vor%

Ich hoffe, das funktioniert für zukünftige Versionen von React. Hier ist der CodePen der es funktioniert:

Ссылка

Danke an @mrlew für den Link, der mir den Hinweis gegeben hat, wie ich das beheben kann und auch dank @Wildhoney für das Denken auf den gleichen Wellenlängen wie ich =).

    
josephnvu 17.06.2016, 22:53
quelle
2

Ich habe einen Fehler behoben, der den Code von @ josephvnus akzeptierter Antwort bereinigt hat. Ich veröffentlichte es als ein NPM-Paket hier: Ссылка

Die Verwendung läuft wie folgt ab

Installieren

yarn add react-shadow-dom-retarget-events oder

npm install react-shadow-dom-retarget-events --save

Verwenden Sie

importiere retargetEvents und rufe es auf dem shadowDom

auf %Vor%

Als Referenz ist dies der vollständige Quellcode des Fixes Ссылка

    
Lukas 09.08.2017 13:40
quelle
0

Das Ersetzen von this.el = this.createShadowRoot(); mit this.el = document.getElementById("mountReact"); hat gerade funktioniert. Vielleicht, weil react einen globalen Event-Handler hat und shadow dom eine Retargeting-Funktion für Ereignisse beinhaltet.

    
mrlew 17.06.2016 00:48
quelle
0

Ich habe zufällig eine andere Lösung entdeckt. Verwenden Sie preact-compat anstelle von react . Scheint in einem ShadowDOM gut zu funktionieren; Preact muss anders an Ereignisse gebunden sein?

    
William Hilton 10.01.2018 05:02
quelle