3
votes

créer des éléments personnalisés dans iframe

Étant donné que les importations html ne sont pas encore bien prises en charge (Firefox, par exemple, n'a pas l'intention de le faire), j'ai essayé d'imiter son utilisation pour importer des éléments personnalisés via des iframes.

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

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

Cependant, la façon dont j'ai essayé ne fonctionne pas (testé dans google chrome et firefox):

// iframe.js

class XAElement extends HTMLElement{
 constructor(){
  super()
  // Any customization here
 }
 // Any other methods for functionality
}
top.customElements.define('x-a', XAElement)

Est-il autorisé à définir des éléments personnalisés du contexte de navigation supérieur dans un iframe?

Remarque: Le file 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 est 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.


2 commentaires

Vous essayez de déclarer la classe d'élément personnalisé dans le contexte iframe mais vous définissez l'élément personnalisé dans le conteneur supérieur qui est un contexte javascript différent. Pourquoi ne définissez-vous pas l'élément personnalisé dans le contexte iframe?


@Supersharp, Si je définis l'élément personnalisé dans le contexte de navigation iframe, l'élément personnalisé ne fonctionne pas dans le contexte de navigation supérieur.


3 Réponses :


1
votes

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

<iframe src="XA.html" onload="defineXA()"></iframe>

Notez que la prise en charge native des importations HTML dans Chrome sera supprimée 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 cet article sur les Alternatives d'importation HTML .


Si vous souhaitez toujours utiliser un élément pour charger un fichier HTML, vous devrez attendre que le fichier soit rechargé avant d'accéder à son contenu.

XXX

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


2 commentaires

Ok, je pense que je vais suivre cette approche. Mais, avant de le faire, j'aimerais comprendre pourquoi je ne peux pas utiliser une classe définie dans le contexte de navigation iframe pour définir un élément personnalisé dans le contexte de navigation supérieur. En passant, j'ai prévu de supprimer le contexte de navigation iframe après qu'il ait fait tout ce qu'il a à faire; cela affecte-t-il toujours les performances?


@ RaúlArturoChávezSarmiento Parce que le code Javascript ne peut être exécuté que dans son contexte mais je pense que vous l'avez trouvé par vous-même



1
votes

Après avoir modifié le script plusieurs fois pour le tester, 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 est uniquement autorisé à hériter du HTMLElement du contexte de navigation où l'élément personnalisé est défini.

Ensuite, en modifiant le script en:

// iframe.js

class XAElement extends top.HTMLElement{
 constructor(){
  super()
  // Any customization here
 }
 // Any other methods for functionality
}
top.customElements.define('x-a', XAElement)

ça finit par fonctionner.

Je vais suivre cette voie car, après avoir défini l'élément personnalisé et en enregistrant le contenu du modèle requis dans la classe constructeur (en tant que propriétés, peut être fait avant de définir l'élément personnalisé), je peux supprimer l'iframe. De cette façon, je n'ai qu'à charger l'iframe; attendre que ces exigences soient satisfaites; et supprimez l'iframe pour (je pense) rétablir l'impact sur les performances de la création d'un contenu de navigateur imbriqué.

Remarque: Si le script est exécuté avant le chargement des modèles à utiliser, l'enregistrement du contenu du modèle dans le constructeur devrait être placé dans un écouteur d'événement de chargement.

Edition:

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, c'est qu'il cesse de fonctionner; c'est pourquoi j'accepte l'autre réponse.


0 commentaires

0
votes

Honnêtement, j'éviterais d'essayer de charger un composant Web en utilisant des importations HTML. Il est obsolète et va être 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 regrouper votre modèle dans un fichier JS, y compris component-build- outils ou Webpack ou autres.

Mon conseil est d'arrêter d'utiliser la technologie morte et de se convertir aux paradigmes actuels de chargement de module.


0 commentaires