IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Désactiver les évéments de la molette de la souris sur des sliders


Sujet :

JavaScript

  1. #1
    Membre averti
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2014
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2014
    Messages : 27
    Par défaut Désactiver les évéments de la molette de la souris sur des sliders
    Bonjour

    J’utilse node-red pour un projet de gestion d'énergie perso. J'ai créé une page pour la gestion de mon chauffage électrique. J’augmente un peu le nombre de zones pour mieux gérer ma conso.
    Sur cette page, j’ai beaucoup de slider et la page est assez grande avec les programmations horaires.

    Le problème, lorsque je descends la page avec la molette de la souris, si je passe sur un slider, ça modifie sa valeur. Si je ne fait pas attention, ça peut être embêtant.

    J’essaie depuis un moment de désactivé les événements liés à la molette de la souris pour les sliders sans succès.

    Je débute avec node-red et javascript. ChatGPT m’aide bien, je l'avoue. Et m'a donné des pistes pour intercepter l'évènement de la molette et essayer de l'ignorer. Sans succès.

    Voici un des code testé
    Les évènements sont bien détectés, mais la molette reste toujours active sur les sliders.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    <script>
        (function() {
            // Fonction pour désactiver la molette sur un slider
            function disableSliderWheel(slider) {
                slider.addEventListener('wheel', (event) => {
    console.log(`Desactivation molette slider ${slider}`);
                    event.stopImmediatePropagation(); // Empêche tout autre écouteur d'exécuter cet événement
                    event.preventDefault(); // Annule le comportement par défaut
                }, { passive: false }); // Permet de prévenir explicitement l'événement
            }
     
            // Observer les changements dans le DOM
            const observer = new MutationObserver((mutations) => {
                mutations.forEach((mutation) => {
                    if (mutation.type === 'childList') {
    console.log(`Mutation détectée`);
                        // Rechercher tous les sliders ajoutés dynamiquement
                        const sliders = document.querySelectorAll('md-slider');
                        sliders.forEach((slider) => {
                            if (!slider.dataset.wheelDisabled) {
                                disableSliderWheel(slider);
                                slider.dataset.wheelDisabled = true; // Marquer comme traité
                            }
                        });
                    }
                });
            });
     
            // Configurer l'observation pour tout le document
            observer.observe(document.body, {
                childList: true,
                subtree: true
            });
     
            // Désactiver la molette pour les sliders déjà présents au chargement
            document.addEventListener("DOMContentLoaded", () => {
                const sliders = document.querySelectorAll('md-slider');
                sliders.forEach((slider) => {
    console.log(`Desactivation molette slider déjà présent ${slider}`);
                    disableSliderWheel(slider);
                    slider.dataset.wheelDisabled = true;
                });
            });
        })();
    </script>

  2. #2
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 671
    Par défaut
    comment sont créés les sliders ? avec une balise input ?
    https://developer.mozilla.org/fr/doc...nt/input/range

  3. #3
    Membre averti
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2014
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2014
    Messages : 27
    Par défaut
    Les sliders sont créés par node-red. Je n'ai pas la main dessus.

    Le débogueur me donne :
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    <md-slider class="ng-untouched ng-valid fl…ng-dirty ng-valid-parse" ng-if="me.item.outs==='all'" flex="100" min="1" max="5" 
    step="1" ng-model="me.item.value" aria-label="Mode Général" ng-change="me.valueChanged(10)" 
    ng-on-wheel="me.wheel($event)" style="z-index: 1; touch-action: none; min-width: 32px;" 
    ng-attr-md-vertical="{{ (me.item.width < me.item.height) || undefined}}" ng-attr-md-invert="{{ me.item.invert || undefined}}" 
    aria-invalid="false" data-wheel-disabled="true">

    C'est peut être la meilleure solution, créer moi même les sliders et pouvoir les contrôler à ma façon.

  4. #4
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 671
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 671
    Par défaut
    je ne connais pas node-red, est ce qu'il génère le code html et vous pouvez seulement ajouter du code javascript ?

    si c'est ça, vous pouvez peut-être essayer d'utiliser le code javascript pour remplacer l'élément par une balise input qui ne réagit pas à la molette.

  5. #5
    Membre averti
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2014
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2014
    Messages : 27
    Par défaut
    Oui, c'est exactement ça. Node red génère le html. J'ai juste des blocs à assembler. Ils appellent ça des flux avec des nœuds et des liaisons entre les nœuds. C'est super efficace pour automatiser un système. Ça facilite énormément la programmation. On peut rajouter des nœuds template pour injecter son propre code html ou/et javascript.

    Par contre, on n'a pas accès au code, il le génère automatiquement et directement.

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 209
    Par défaut
    Bonjour,
    on a quand même l'impression qu'il y a de l'Angular derrière tout cela.
    ng-on-wheel="me.wheel($event)"
    est-ce une directive valide ? Si oui qu'y a-t-il dedans c'est là qu'il faudrait supprimer l'action par défaut !

    En JavaScript « vanilla » il te faudrait juste écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    "use strict";
    // Initialisation après chargement du DOM
    document.addEventListener("DOMContentLoaded", () => {
      const allRange = document.querySelectorAll("md-slider");
      allRange.forEach((el) => {
        el.addEventListener("wheel", (e) => e.preventDefault());
      });
    });
    ce qui est proche de ce que tu as fait.

  7. #7
    Membre averti
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2014
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2014
    Messages : 27
    Par défaut
    Citation Envoyé par NoSmoking Voir le message
    Bonjour,
    on a quand même l'impression qu'il y a de l'Angular derrière tout cela.
    Je pense que tu as raison

    Citation Envoyé par NoSmoking Voir le message
    est-ce une directive valide ? Si oui qu'y a-t-il dedans c'est là qu'il faudrait supprimer l'action par défaut !
    Qu'est ce que tu entends par là ?

    Citation Envoyé par NoSmoking Voir le message
    En JavaScript « vanilla » il te faudrait juste écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    "use strict";
    // Initialisation après chargement du DOM
    document.addEventListener("DOMContentLoaded", () => {
      const allRange = document.querySelectorAll("md-slider");
      allRange.forEach((el) => {
        el.addEventListener("wheel", (e) => e.preventDefault());
      });
    });
    ce qui est proche de ce que tu as fait.
    Je viens de tester ton code. Je pense que c'est la bonne voie. Mais ça ne fonctionne toujours pas.

    Voici une capture d'écran du débogueur
    Nom : Capture d’écran du 2024-12-08 17-42-25.png
Affichages : 73
Taille : 134,2 Ko
    Il y une fonction e() qui semlbe s'occuper des évènements. En désactivant sa propagation pour la molette, elle n'a plus d'influence sur le slider selectionné. C'est ce que je souhaite. Maintenant, il faudrait y arriver sans avoir besoin de passer par le débogueur

  8. #8
    Membre averti
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2014
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2014
    Messages : 27
    Par défaut
    J'ai trouvé une solution.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    const intercepterMolette = (slider) => {
           slider.addEventListener("wheel", (event) => {
                   console.log(`Événement wheel bloqué pour : ${slider.getAttribute("aria-label")}`);
                    event.stopImmediatePropagation();
                    event.preventDefault();
           }, { capture: true });
    };
    En rajoutant capture: true, ça change tout. ça intercepte l'événement dans la phase de capture, avant que d'autres gestionnaires puissent intervenir.

    Au choix, en exécutant cette fonction lors d'une mutation avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
            const observer = new MutationObserver(() => {
                console.log("Changement détecté");
                const sliders = document.querySelectorAll("md-slider:not([data-wheel-fixed])");
                console.log(`Mut-Sliders trouvés : ${sliders.length}`);
                sliders.forEach((slider) => {
                    console.log(`Mut-pour le curseur : ${slider.getAttribute("aria-label")}`);
                    intercepterMolette(slider);
                    slider.setAttribute("data-wheel-fixed", "true"); // Marquer comme traité
                });
            });
            // Observez les ajouts dans le DOM
            observer.observe(document.body, { childList: true, subtree: true });
    Ou en en attendant un peu que le page soit totalement charger
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
            setTimeout(() => {
                console.log("Délai ajouté pour le chargement");
                const sliders = document.querySelectorAll("md-slider");
                console.log(`Sliders trouvés : ${sliders.length}`);
                sliders.forEach((slider) => {
                    intercepterMolette(slider);
                });
            }, 1000);
    Le résultat est celui escompté

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 19/01/2011, 22h08
  2. Récupérer les événements de la molette de la souris
    Par Delbeke dans le forum Vos contributions VB6
    Réponses: 13
    Dernier message: 05/12/2007, 00h39
  3. Réponses: 3
    Dernier message: 25/10/2007, 20h41
  4. afficher les corrdonnées x et y de la souris sur une image
    Par bubuche87 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 27/06/2007, 13h28
  5. Réponses: 1
    Dernier message: 13/05/2007, 15h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo