With HTML syntax it is not possible as it is static. You can even create a preprocessor that does what you want, which would facilitate maintenance, but in the final code would end up being the same thing.
With Javascript, using attributes data
Without breaking the syntax of HTML, with the help of Javascript you could do something like:
<input type="text" data-events="(click, keydown)=funcaojs" />
The code to analyze this could be quite simple or quite elaborate, depending on your needs. In this case, it could be something like:
const elements = document.querySelectorAll('[data-events]')
const pattern = /^\((.*)\)=(.*)$/
for (let element of elements) {
let config = element.dataset.events
let groups = config.match(pattern)
if (groups) {
let events = groups[1].split(',').map(event => event.trim())
let handler = groups[2]
for (let event of events) {
console.log(`Adicionando a função ${handler} ao evento ${event}`)
element.addEventListener(event, window[handler])
}
}
}
// Função que tratará os eventos
function funcaojs(event) {
console.log(`Evento ${event.type} disparado em um ${event.target.tagName}`)
}
<input type="text" data-events="(click, keydown)=funcaojs" />
It is a very simple example and perhaps it is not completely functional to put into production, because my intention was just to make the proof of concept of the solution. You can (and should) adapt it to your needs.
But it is important to note that although it is a simple code it adapts to the amount of elements you have on the page. That is, you can use the same attribute data-events
in any element you wish:
const elements = document.querySelectorAll('[data-events]')
const pattern = /^\((.*)\)=(.*)$/
for (let element of elements) {
let config = element.dataset.events
let groups = config.match(pattern)
if (groups) {
let events = groups[1].split(',').map(event => event.trim())
let handler = groups[2]
for (let event of events) {
console.log(`Adicionando a função ${handler} ao evento ${event}`)
element.addEventListener(event, window[handler])
}
}
}
// Função que tratará os eventos
function funcaojs(event) {
console.log(`Evento ${event.type} disparado em um ${event.target.tagName}`)
}
<input type="text" data-events="(click, keydown)=funcaojs" />
<button data-events="(click)=funcaojs">Pressione-me</button>
<h1 data-events="(mouseenter, mouseleave)=funcaojs">Passe o mouse</h1>
Note: I used the function in all events funcaojs
to simplify the code and already display the log message on the console, but you can change and define the function you want.
With Javascript, using the prototype
As shown in the other responses, it is possible to add a function to an event through the addEventListener
, but it does not accept more than one event, so you need to call the function for each event you want to treat. Or you can benefit from the prototype
Javascript, because with it you can define new methods to its elements without necessarily interfering in the natural behavior of the same.
So we can create the function addEventsListener
(understand Events
plural) so that you accept a list of events for the same function, basically doing what you need:
HTMLElement.prototype.addEventsListener = function (events, listener) {
for (let event of events) {
this.addEventListener(event, listener)
}
}
And with that, we can call the method addEventsListener
in any HTML element we wish to pass the event list:
input.addEventsListener(['click', 'keydown'], funcaojs)
It would look something like this:
// Define a função no prototype
HTMLElement.prototype.addEventsListener = function (events, listener) {
for (let event of events) {
this.addEventListener(event, listener)
}
}
// Define a função que tratará os eventos
function funcaojs(event) {
console.log(`Evento ${event.type} disparado em um ${event.target.tagName}`)
}
// Atribui a função aos eventos
const input = document.querySelector('input')
input.addEventsListener(['click', 'keydown'], funcaojs)
<input type="text" />
Note: the native function addEventListener
accepts more than two parameters, so it would be interesting that the defined function addEventsListener
treated the same parameters to maintain all types of compatibility between calls. To simplify, I only implemented the first two, which are the event and the function that deals with the same.
I believe that this is not possible if you want to call the same function, but by grouping two events, you have to create an event in the same way for the element and put the function you want to call.
– Leandro Nascimento
@Leandronascimento, can give an example?
– edro
The first code you wrote on top is what I’m referring to. It’s not possible that you want!
– Leandro Nascimento