IronWoods.es

Desarrollo web

Blog / JavaScript / Funcionamiento de un icono dentro de un botón

Al añadir un icono a un botón (o a otro elemento que vamos a pulsar), la activación puede no desencadenar el comportamiento esperado, al usar JavaScript para manejar el evento.

Caso práctico

Hay que añadir a la página un botón, con un icono de un corazón, junto a el número de pulsaciones registrado, si las hay, como este:

Captura con botton de ejemplo
Botón con un icono en su interior

El código que presento a continuación es muy tonto, uso la ID del botón para asociarle un evento y al producirse este, trato de recuperar esa misma ID del evento, lo que inicialmente no siempre funciona. Lo importante es el evento, que es el que "inicia" la lógica del programa. Saber cómo recuperar la ID, en el contexto de este ejemplo no tiene importancia, pero mucha en casos reales donde generalmente hay múltiples botones, que se recuperan y se recorren para añadirles el "listener" y el script correspondiente en el que se requiere identificar el elemento pulsado.

HTML:


<div>
    <span>Lorem ipsum</span>

    <button id="btn">
        5
        <svg height="18" width="26" ...>
            <path d="..." />
        </svg>
    </button>
</div>

Comportamiento esperado:

Al hacer clic sobre el botón se recoge la ID del botón y se suma una unidad al contador asociado.

El primer paso es obtener la ID del botón pulsado (hay más botones en la página).

JavaScript de partida:


document.getElementById('btn')
    .addEventListener('click', function(event) {
    const buttonId = event.target.id;

    console.log('clicked button wit ID: ' + buttonId);
});

Comportamiento obtenido:

Al hacer clic sobre el botón se recoge el evento e imprime la traza, pero se dan dos situaciones:

1. Si se clica sobre el icono, la traza no muestra la ID del botón.

2. Si se pulsa fuera del área del icono el comportamiento es el esperado, es decir, se recoge la ID del botón del target.

JavaScript que funciona:


document.getElementById('btn')
    .addEventListener('click', function(event) {
    const buttonId = event.target.id
        ? event.target.id
        : event.currentTarget.id;

    console.log('clicked button wit ID: ' + buttonId);
});

El código anterior funciona con el HTML presentado, pero si el SVG tuviera un ID propio, la ternaria hace que nos devuelva este ID al clicarlo y no el del botón. Una pequeña "corrección" hace el código más sencillo y universal:


document.getElementById('btn')
    .addEventListener('click', function(event) {
    const buttonId = event.currentTarget.id;

    console.log('clicked button wit ID: ' + buttonId);
});

La documentación de MDN sobre Event.currentTarget indica:

"Identifica el target (objetivo) actual del evento, ya que el evento atraviesa el DOM. Siempre hace referencia al elemento al cual el controlador del evento fue asociado, a diferencia de event.target, que identifica el elemento en el que se produjo el evento".