3 votes

Créer des éléments personnalisés dans un iframe

Étant donné que les importations HTML ne sont pas encore bien supportées (Firefox, par exemple, n'a aucun plan pour le faire), j'ai essayé de reproduire son utilisation en important des éléments personnalisés via des iframes.

La manière dont j'ai essayé de le faire est en chargeant un script dans l'iframe qui définit l'élément personnalisé dans le contexte de navigation principal ; et l'iframe pourrait même être supprimé du document après cela. La raison pour laquelle j'ai essayé de le faire est parce que j'aimerais définir dynamiquement des éléments personnalisés en fonction des informations que j'obtiens du côté client ; et ces éléments personnalisés utilisent des modèles pour être utilisés dans le shadow DOM.

Je préfère utiliser des modèles au lieu de construire le shadow DOM dans le script afin d'avoir un code propre ; c'est pourquoi j'aimerais reproduire la fonctionnalité d'importation avec un iframe contenant tous les modèles au lieu de simplement charger un script où le shadow DOM est construit.

Cependant, la manière dont j'ai essayé ne fonctionne pas (testé sur Google Chrome et Firefox) :

// iframe.js

class XAElement extends HTMLElement{
 constructor(){
  super()
  // Toute personnalisation ici
 }
 // Toutes les autres méthodes pour la fonctionnalité
}
top.customElements.define('x-a', XAElement)

Est-il permis de définir des éléments personnalisés du contexte de navigation principal dans un iframe ?

Note : Le fichier iframe.html est n'importe quel fichier HTML qui charge ce script ; et le fichier index.html (dans lequel l'erreur se produit) est n'importe quel fichier qui charge l'iframe iframe.html.

Note 2 : L'erreur que j'obtiens se produit après super() ; cependant, si je commente la dernière ligne (dans laquelle j'ai l'intention de définir l'élément personnalisé), aucune erreur ne se produit.

1voto

Supersharp Points 11362

Si vous voulez imiter les imports HTML, vous feriez mieux d'utiliser la bibliothèque HTMLImports.min.js fournie dans le dépôt Github.

Notez que le support natif des imports HTML dans Chrome sera supprimé dans la prochaine version (version 73) car aucun consensus n'a été trouvé avec Mozilla et Apple sur cette fonctionnalité proposée par Google... mais la bibliothèque ci-dessus fonctionnera toujours comme un simple chargeur HTML.


Alternativement, vous pouvez charger du contenu HTML avec fetch() comme décrit dans ce post sur les alternatives aux imports HTML.


Si vous voulez toujours utiliser un élément </code> pour charger un fichier HTML, vous devrez attendre que le fichier soit chargé avant d'accéder à son contenu.</p> <pre><code><iframe src="XA.html" onload="defineXA()">

Je ne pense pas que ce soit une bonne pratique car cela créera un contexte de navigation inutile.

1voto

Après avoir modifié le script plusieurs fois pour les tests, j'ai réalisé que HTMLElement était différent de top.HTMLElement. C'est pourquoi l'héritage de HTMLElement n'a pas fonctionné pour définir un élément personnalisé, car il n'est autorisé à hériter que de HTMLElement du contexte de navigation où l'élément personnalisé est défini.

Ensuite, en modifiant le script comme suit :

// iframe.js

class XAElement extends top.HTMLElement{
 constructor(){
  super()
  // Personnalisation ici
 }
 // Autres méthodes pour la fonctionnalité
}
top.customElements.define('x-a', XAElement)

cela fonctionne finalement.

Je vais opter pour cette approche car, après avoir défini l'élément personnalisé et enregistré le contenu du modèle requis dans la classe du constructeur (en tant que propriétés, pouvant être faites avant de définir l'élément personnalisé), je peux supprimer l'iframe. De cette manière, je n'ai qu'à charger l'iframe ; attendre que ces exigences soient remplies ; et supprimer l'iframe pour (je pense) annuler l'impact sur les performances de la création d'un contenu de navigateur imbriqué.

Remarque : Si le script est exécuté avant que les modèles à utiliser ne soient chargés, l'enregistrement du contenu du modèle dans le constructeur doit être placé à l'intérieur d'un écouteur d'événements de chargement.

Édition :

J'ai oublié de tester ce qui se passe si je supprime l'iframe au moment de poster la réponse. Ce qui se passe est que cela cesse de fonctionner ; c'est pourquoi j'accepte l'autre réponse.

0voto

user1253074 Points 11

Honnêtement, je éviterais d'essayer de charger un composant Web en utilisant des imports HTML. Il est déprécié et sera supprimé de tous les navigateurs.

Au lieu de cela, commencez à utiliser des modules ES6 ou même créez simplement des fichiers JavaScript traditionnels.

Il existe de nombreuses façons de packager votre modèle dans un fichier JS, y compris component-build-tools ou Webpack ou d'autres choses.

Mon conseil est d'arrêter d'utiliser une technologie obsolète et de passer aux paradigmes actuels du chargement de modules.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X