107 votes

Ajouter plusieurs écouteurs d'événements à un seul élément

Alors mon dilemme est que je ne veux pas écrire le même code deux fois. Une fois pour l'événement de clic et une autre pour l'événement touchstart.

Voici le code original:

document.getElementById('first').addEventListener('touchstart', function(event) {
    do_something();
    });

document.getElementById('first').addEventListener('click', function(event) {
    do_something(); 
    });

Comment puis-je simplifier cela ? Il DOIT y avoir un moyen plus simple!

240voto

Allan Nienhuis Points 693

Je pensais que certains pourraient trouver cette approche utile; elle pourrait être appliquée à tout code aussi répétitif:

ES6

['click','ontouchstart'].forEach( evt => 
    element.addEventListener(evt, dosomething, false)
);

ES5

['click','ontouchstart'].forEach( function(evt) {
    element.addEventListener(evt, dosomething, false);
});

45voto

Esailija Points 74052

Vous pouvez simplement définir une fonction et la passer. Les fonctions anonymes ne sont pas spéciales en aucune façon, toutes les fonctions peuvent être passées comme des valeurs.

var elem = document.getElementById('first');

elem.addEventListener('touchstart', handler, false);
elem.addEventListener('click', handler, false);

function handler(event) {
    faites_quelque_chose();
}

33voto

KooiInc Points 38845

Peut-être pouvez-vous utiliser une fonction d'aide comme ceci :

// events and args should be of type Array
function addMultipleListeners(element,events,handler,useCapture,args){
  if (!(events instanceof Array)){
    throw 'addMultipleListeners: '+
          'please supply an array of eventstrings '+
          '(like ["click","mouseover"])';
  }
  //create a wrapper to be able to use additional arguments
  var handlerFn = function(e){
    handler.apply(this, args && args instanceof Array ? args : []);
  }
  for (var i=0;i

`[**Édité nov. 2020**] Cette réponse est assez ancienne. La façon dont je résous cela de nos jours est en utilisant un objetactionsoù les gestionnaires sont spécifiés par type d'événement, undata-attribut` pour un élément pour indiquer quelle action doit être exécutée dessus et une méthode générique de gestionnaire globale (donc délégation d'événements).

const firstElemHandler = (elem, evt) =>
  elem.textContent = `Vous avez ${evt.type === "click" ? "cliqué" : "touché"} !`;
const actions = {
  click: {
    firstElemHandler,
  },
  touchstart: {
    firstElemHandler,
  },
  mouseover: {
    firstElemHandler: elem => elem.textContent = "Maintenant ... cliquez sur moi !",
    outerHandling: elem => {
      console.clear();
      console.log(`Salut depuis outerHandling, heure de traitement ${
        new Date().toLocaleTimeString()}`);
    },
  }
};

Object.keys(actions).forEach(key => document.addEventListener(key, handle));

function handle(evt) {
  const origin = evt.target.closest("[data-action]");
  return origin &&
    actions[evt.type] &&
    actions[evt.type][origin.dataset.action] &&
    actions[evt.type][origin.dataset.action](origin, evt) ||
    true;
}

[data-action]:hover {
  cursor: pointer;
}

    Survolez, cliquez ou touchez

  ceci est également géré (au survol de la souris)``

13voto

Torsten Walter Points 3213

Pour un grand nombre d'événements, cela pourrait vous aider :

var element = document.getElementById("myId");
var myEvents = "click touchstart touchend".split(" ");
var handler = function (e) {
    faire quelque chose
};

for (var i=0, len = myEvents.length; i < len; i++) {
    element.addEventListener(myEvents[i], handler, false);
}

Mise à jour 06/2017 :

Maintenant que de nouvelles fonctionnalités de langage sont plus largement disponibles, vous pourriez simplifier l'ajout d'une liste limitée d'événements qui partagent un écouteur.

const element = document.querySelector("#myId");

function handleEvent(e) {
    // faire quelque chose
}
// Je préfère string.split car cela rend légèrement plus facile l'édition de la liste des événements

"click touchstart touchend touchmove".split(" ")
    .map(name => element.addEventListener(name, handleEvent, false));

Si vous souhaitez gérer de nombreux événements et avoir des exigences différentes par écouteur, vous pouvez également passer un objet que la plupart des gens ont tendance à oublier.

const el = document.querySelector("#myId");

const eventHandler = {
    // appelé pour chaque événement sur cet élément
    handleEvent(evt) {
        switch (evt.type) {
            case "click":
            case "touchstart":
                // click et touchstart partagent un gestionnaire de clic
                this.handleClick(e);
                break;
            case "touchend":
                this.handleTouchend(e);
                break;
            default:
                this.handleDefault(e);
        }
    },
    handleClick(e) {
        // faire quelque chose
    },
    handleTouchend(e) {
        // faire quelque chose de différent
    },
    handleDefault(e) {
        console.log("événement non géré : %s", e.type);
    }
}

el.addEventListener(eventHandler);

Mise à jour 05/2019 :

const el = document.querySelector("#myId");

const eventHandler = {
    handlers: {
        click(e) {
            // faire quelque chose
        },
        touchend(e) {
            // faire quelque chose de différent
        },
        default(e) {
            console.log("événement non géré : %s", e.type);
        }
    },
    // appelé pour chaque événement sur cet élément
    handleEvent(evt) {
        switch (evt.type) {
            case "click":
            case "touchstart":
                // click et touchstart partagent un gestionnaire de clic
                this.handlers.click(e);
                break;
            case "touchend":
                this.handlers.touchend(e);
                break;
            default:
                this.handlers.default(e);
        }
    }
}

Object.keys(eventHandler.handlers)
    .map(eventName => el.addEventListener(eventName, eventHandler))

9voto

Mattias Buelens Points 7690

Sauf si votre fonction do_something fait effectivement quelque chose avec les arguments donnés, vous pouvez simplement la passer en tant que gestionnaire d'événements.

var first = document.getElementById('first');
first.addEventListener('touchstart', do_something, false);
first.addEventListener('click', do_something, false);

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