Déclencher JavaScript lors du clic sur n'importe quel lien de la page, mais avant le chargement du contenu de la page

Bonjour.
Lorsque nous changeons de page dans Discourse, les étapes apparentes sont les suivantes :

  1. Nous cliquons sur le lien
  2. Le contenu actuel disparaît et le chargeur s’affiche
  3. L’URL est mise à jour et le nouveau contenu apparaît

Cela diffère légèrement lorsque nous passons d’une page à l’accueil, car l’URL est modifiée pour l’URL de l’accueil lorsque le contenu actuel disparaît, et non lorsque le nouveau contenu apparaît.

Mon objectif est d’avoir un script qui s’exécute dès que nous cliquons sur n’importe quel lien de page dans Discourse.
api.onPageChange ne convient pas dans ce cas, car le code est exécuté presque en même temps que le chargement du contenu de la nouvelle page.

Existe-t-il une méthode Discourse pour cela ? J’ai examiné les déclencheurs d’événements, mais je n’en ai trouvé aucun correspondant à ce dont j’ai besoin.

1 « J'aime »

Salut :wave:

Actuellement, aucune méthode dans l’API des plugins ne permet d’exécuter un script avant une transition de page, car cela ne s’est pas présenté auparavant, du moins à ma connaissance.

Cela dit, vous pouvez utiliser l’action willTransition() dans la route de l’application :

Vous pourriez utiliser quelque chose comme ceci dans votre thème ou composant :

// Ceci s'exécute après la transition
api.onPageChange((url, title) => {
  console.log("après la transition");
});

// Ceci s'exécute juste avant la transition
api.modifyClass("route:application", {
  pluginId: "some-name",
  actions: {
    willTransition() {
      // exécuter d'abord le code principal
      this._super(...arguments);
      // puis effectuer certaines tâches
      console.log("avant la transition");
      // vous pouvez aussi faire quelque chose comme ceci pour voir quelles données vous avez
      // à traiter, comme _router
      console.log(this)
    }
  }
});
6 « J'aime »

Exactement ce qu’il me fallait. Merci !

2 « J'aime »

Cela ne semble pas se déclencher lors de l’entrée dans un sujet à partir d’une liste de sujets ?

J’ai aussi essayé d’en ajouter un :

      api.modifyClass("route:topic", {
        pluginId: PLUGIN_ID,
        actions: {
          willTransition() {

mais cela ne se déclenche pas non plus.

Quelques raisons pour lesquelles cela pourrait ne pas fonctionner :

  1. Mettre des actions dans un hash est une ancienne syntaxe que nous n’utilisons plus dans Discourse. Théoriquement, cela devrait fonctionner, mais l’interopérabilité avec la nouvelle syntaxe pourrait ne pas être parfaite. La manière moderne serait

    api.modifyClass("route:application", (Superclass) => class extends Superclass {
      @action
      willTransition() {
        console.log("faire quelque chose");
        super.willTransition(...arguments);
      }
    });
    

    Le disclaimer standard modifyClass s’applique : c’est risqué et cela pourrait casser à tout moment

  2. Je ne pense pas que willTransition soit garanti de se déclencher sur la route d’application dans toutes les situations. (par exemple, si une route enfant a une action willTransition, elle ne remontera pas nécessairement)

Je recommanderais d’utiliser les événements du service de routage Ember à la place : RouterService | 5.12.0 | Ember API Documentation
par exemple, quelque chose comme

const router = api.container.lookup("service:router");
router.on("routeWillChange", () => {
  console.log("route will change déclenché");
});
2 « J'aime »

Bien, merci David, j’essaierai ça ensuite !

Cette enquête a été déclenchée (ahem) parce que j’avais besoin d’un moyen de déclencher quelque chose à chaque changement de page, et avant le rendu.

L’événement d’API de changement de page ne semble pas garanti de se déclencher avant le rendu des éléments de la page, apparemment.

1 « J'aime »

Je pense que vous aurez du mal à faire cela parfaitement. Ember s’attend à avoir le contrôle total du rendu, donc essayer de s’accrocher à des points arbitraires sera difficile et pourrait causer des problèmes (selon ce que vous essayez de faire).

Évidemment, je ne sais pas quel est votre objectif final… donc peut-être que la douleur est justifiée. Auquel cas : n’hésitez pas à m’ignorer :wink:

(bien sûr, si vous souhaitez ouvrir un sujet Dev sur le problème que vous essayez de résoudre, je serais heureux d’y jeter un œil)

Heureux d’être explicite car le code est open source :

Je travaille avec un fournisseur de publicité tiers et ils ont une fonction de réinitialisation de page publicitaire en javascript qui doit être exécutée avant que les publicités de la nouvelle page ne soient déclenchées.

Toute amélioration est la bienvenue et je l’ai déjà implémentée dans la liste des sujets avec le code de Johani. (dans un PR ouvert).

Mais cela a laissé le sujet… J’essaierai votre suggestion ensuite et l’adopterai dans les deux cas si cela améliore encore les choses.

Ah je vois, donc vous ne modifiez pas le DOM directement :ok_hand:

Dans ce cas, j’espère que routeWillChange fonctionnera - il devrait certainement se déclencher avant que la prochaine route ne soit rendue.

La mise en garde est que… dans le cas de choses comme les redirections, il peut se déclencher deux fois. Ou peut se déclencher, puis la transition finit par être abandonnée. Mais peut-être que c’est acceptable dans ce cas.

2 « J'aime »

Oui, pas de modification directe du DOM ici chez Merefield Technology Towers. :sweat_smile:

Oui, j’utiliserai le service, c’est à cela qu’il sert ! Je reviendrai avec mon expérience car je suis sûr que les résultats pourraient intéresser d’autres personnes.

3 « J'aime »

Oui, cela nettoie et les choses se déroulent maintenant dans le bon ordre sur les deux itinéraires.

:rocket:

Merci pour votre aide !

2 « J'aime »