Tengo un detector de eventos para click en eventos en el document y estoy usando composedPath para determinar si algo en la ruta incluye un determinado atributo.
Si algo en la ruta incluye un atributo que escucho, entonces todo está bien y todo funciona.
Sin embargo, si algo en la ruta no incluye un atributo que escucho, arroja una excepción:
"TypeError no detectado: el.hasAttribute no es una función"
Aquí hay un violín que muestra esto:
document.addEventListener('click', (event) => { const includesAttribute = event.composedPath().some((el) => el.hasAttribute('my-attribute')); console.log(`has attribute: ${includesAttribute}`); }); <button my-attribute>click me, I log true and work fine</button> <br/> <button other-attribute>click me, I throw an exception because I don't have the attribute</button> ¿Por qué obtengo una excepción solo cuando el atributo no existe? ¿No debería estar siempre disponible el método hasAttribute ?
Porque eldocument no tiene el método getAttribute . Su llamada a some está llegando hasta el final para document cuando no encuentra nada; vea el registro de nodeName aquí:
document.addEventListener('click', (event) => { const includesAttribute = event.composedPath().some((el) => { console.log(el.nodeName); return el.hasAttribute('my-attribute'); }); console.log(`has attribute: ${includesAttribute}`); }); <button my-attribute>click me, I log true and work fine</button> <br/> <button other-attribute>click me, I throw an exception but now you can see why</button>Solo agrega un guardia:
document.addEventListener('click', (event) => { const includesAttribute = event.composedPath().some((el) => el.hasAttribute && el.hasAttribute('my-attribute')); console.log(`has attribute: ${includesAttribute}`); }); document.addEventListener('click', (event) => { const includesAttribute = event.composedPath().some((el) => el.hasAttribute && el.hasAttribute('my-attribute')); console.log(`has attribute: ${includesAttribute}`); }); <button my-attribute>click me, I log true and work fine</button> <br/> <button other-attribute>click me, I do not throw an exception anymore</button>