Donc, mon dilemme est que je ne veux pas écrire le même code deux fois. Une fois pour l'événement click et un 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 compacter cela? Il doit y avoir un moyen plus simple!
Peut-être que vous pouvez utiliser une fonction d'assistance comme celle-ci:
// 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<events.length;i+=1){
element.addEventListener(events[i],handlerFn,useCapture);
}
}
function handler(e) {
// do things
};
// usage
addMultipleListeners(
document.getElementById('first'),
['touchstart','click'],
handler,
false);
Je sais que c’est une vieille question, mais j’ai pensé que certains pourraient trouver cette approche utile; il pourrait être appliqué à tout code répétitif similaire:
ES6
['click','ontouchstart'].forEach( evt =>
element.addEventListener(evt, dosomething, false)
);
ES5
['click','ontouchstart'].forEach( function(evt) {
element.addEventListener(evt, dosomething, false);
});
Vous pouvez simplement définir une fonction et la transmettre. Les fonctions anonymes ne sont nullement spéciales, toutes les fonctions peuvent être transmises sous forme de valeurs.
var elem = document.getElementById('first');
elem.addEventListener('touchstart', handler, false);
elem.addEventListener('click', handler, false);
function handler(event) {
do_something();
}
Pour un grand nombre d'événements, cela pourrait aider:
var element = document.getElementById("myId");
var myEvents = "click touchstart touchend".split(" ");
var handler = function (e) {
do something
};
for (var i=0, len = myEvents.length; i < len; i++) {
element.addEventListener(myEvents[i], handler, false);
}
Mise à jour 06/2017:
Maintenant que les nouvelles fonctionnalités linguistiques sont plus largement disponibles, vous pouvez simplifier l'ajout d'une liste limitée d'événements partageant un auditeur.
const element = document.querySelector("#myId");
function handleEvent(e) {
// do something
}
// I prefer string.split because it makes editing the event list slightly easier
"click touchstart touchend touchmove".split(" ")
.map(name => element.addEventListener(name, handleEvent, false));
Si vous souhaitez gérer de nombreux événements et avoir différentes exigences par auditeur, vous pouvez également transmettre un objet que la plupart des gens ont tendance à oublier.
const el = document.querySelector("#myId");
const eventHandler = {
// called for each event on this element
handleEvent(evt) {
switch (evt.type) {
case "click":
case "touchstart":
// click and touchstart share click handler
this.handleClick(e);
break;
case "touchend":
this.handleTouchend(e);
break;
default:
this.handleDefault(e);
}
},
handleClick(e) {
// do something
},
handleTouchend(e) {
// do something different
},
handleDefault(e) {
console.log("unhandled event: %s", e.type);
}
}
el.addEventListener(eventHandler);
À moins que votre fonction do_something
n'effectue réellement quelque chose avec des arguments donnés, vous pouvez simplement le transmettre en tant que gestionnaire d'événements.
var first = document.getElementById('first');
first.addEventListener('touchstart', do_something, false);
first.addEventListener('click', do_something, false);
J'ai une petite solution qui s'attache au prototype
EventTarget.prototype.addEventListeners = function(type, listener, options,extra) {
let arr = type;
if(typeof type == 'string'){
let sp = type.split(/[\s,;]+/);
arr = sp;
}
for(let a of arr){
this.addEventListener(a,listener,options,extra);
}
};
Vous permet de lui donner une chaîne ou un tableau. La chaîne peut être séparée par un espace (''), une virgule (',') OR et un point-virgule (';')
document.getElementById('first').addEventListener('touchstart',myFunction);
document.getElementById('first').addEventListener('click',myFunction);
function myFunction(e){
e.preventDefault();e.stopPropagation()
do_something();
}
Vous devriez utiliser e.stopPropagation()
car sinon, votre fonction sera déclenchée deux fois sur mobile.
Je viens de faire cette fonction (intentionnellement minified):
((i,e,f)=>e.forEach(o=>i.addEventListener(o,f)))(element, events, handler)
Usage:
((i,e,f)=>e.forEach(o=>i.addEventListener(o,f)))(element, ['click', 'touchstart'], (event) => {
// function body
});
La différence par rapport aux autres approches réside dans le fait que la fonction de traitement est définie une seule fois, puis transmise à chaque addEventListener
.
Ajouter une version non-minifiée pour la rendre plus compréhensible. La version abrégée était simplement destinée à être copiée-collée et utilisée.
((element, event_names, handler) => {
event_names.forEach( (event_name) => {
element.addEventListener(event_name, handler)
})
})(element, ['click', 'touchstart'], (event) => {
// function body
});
Semi-lié, mais cela sert à initialiser un écouteur d'événement unique spécifique par élément.
Vous pouvez utiliser le curseur pour afficher les valeurs en temps réel ou consulter la console . Sur l'élément <input>
, j'ai une balise attr
appelée data-whatever
, afin de pouvoir personnaliser ces données si vous le souhaitez.
sliders = document.querySelectorAll("input");
sliders.forEach(item=> {
item.addEventListener('input', (e) => {
console.log(`${item.getAttribute("data-whatever")} is this value: ${e.target.value}`);
item.nextElementSibling.textContent = e.target.value;
});
})
.wrapper {
display: flex;
}
span {
padding-right: 30px;
margin-left: 5px;
}
* {
font-size: 12px
}
<div class="wrapper">
<input type="range" min="1" data-whatever="size" max="800" value="50" id="sliderSize">
<em>50</em>
<span>Size</span>
<br>
<input type="range" min="1" data-whatever="OriginY" max="800" value="50" id="sliderOriginY">
<em>50</em>
<span>OriginY</span>
<br>
<input type="range" min="1" data-whatever="OriginX" max="800" value="50" id="sliderOriginX">
<em>50</em>
<span>OriginX</span>
</div>