web-dev-qa-db-fra.com

Pourquoi la fonction js click s'exécute-t-elle plusieurs fois?

Je crée des fonctionnalités d'accordéon pour les champs et les paragraphes en utilisant une combinaison de modèles twig et un fichier JavaScript personnalisé.

Tout s'imprime comme prévu et la fonctionnalité de base de l'accordéon fonctionne; cependant, le script de la fonction de clic s'exécute plusieurs fois, provoquant un comportement "expand-collapse-expand-collapse ...". Voir l'image:

browser and console view that shows logging of each function iteration on click

Voici le fichier script:

(function($, Drupal) {

/* Add span to wysiwyg button classes for alignment
------------------------------------ */
Drupal.behaviors.accordionFaqFunction = {
  attach: function (context, settings) {
        $('.toggle').click(function(e) {

                e.preventDefault();
                var $this = $(this);

                if ($this.next().hasClass('show')) {
                        $this.next().removeClass('show');
                        $this.next().slideUp(350);
                        console.log("hiding");
                } else {
                        $this.parent().parent().find('li .inner').removeClass('show');
                        $this.parent().parent().find('li .inner').slideUp(350);
                        console.log("showing");
                        $this.next().toggleClass('show');
                        $this.next().slideToggle(350);
                }
        });


  }
};

})(jQuery, Drupal);

Pourquoi le script s'exécute-t-il plusieurs fois?

4
lane

Plus important encore, vous devez utiliser le sélecteur JQuery context. Sinon, vous exécutez l'intégralité du DOM via votre code js à tout moment lorsque Drupal vous transmettent uniquement context à traiter.

Si votre fonction s'exécute toujours plusieurs fois, ajoutez once () avec un identifiant unique:

$('input.myCustom', context).once('mySecondBehavior').each(function () {

N'oubliez pas d'ajouter la bibliothèque core/jquery.once à mytheme.libraries.yml, voir https://www.drupal.org/docs/8/api/javascript-api/javascript-api-overview

10
4k4

Je viens de tomber sur ce post en travaillant sur quelque chose dans notre projet. Nous avons plusieurs événements liés à $ ('corps', contexte) car la flexibilité de la plateforme permet de placer des widgets et autres presque n'importe où dans le corps.

L'utilisation de $('body', context).on('click', '.modal-trigger', function (e) {}); provoquait la liaison de l'événement click sur le corps 2x.

La simple utilisation de $('body', context).once().on('click', '.modal-trigger', function (e) {}); ne liait que le dernier script attaché/chargé au corps, ce qui ne provoquait aucun autre événement de script attaché.

L'ajout de .once () avec un identifiant unique pour chaque script a merveilleusement résolu ce problème.

Ex. 1er script modal

  Drupal.behaviors.SigmaModal = {

    attach: function (context, settings) {

      // Trigger sigma dialog on click.
      $('body', context).once('SigmaModal').on('click', '.sigma-modal-trigger', function (e) {

2e script modal

  Drupal.behaviors.DisplayModal = {

    attach: function (context, settings) {

      // Trigger generic dialogs on click.
      $('body', context).once('DisplayModal').on('click', '.modal-trigger', function (e) {
4
ZhuRenTongKu

Vous pouvez essayer celui-ci sur Drupal 8:

Drupal.behaviors.custom = {
    attach: function(context, settings) {
        if(!Drupal.behaviors.custom.click_set){
            //Your code.
            Drupal.behaviors.custom.click_set = true;
        }
    }
};
1
lucasvm1980