Is the target of MouseEvent always an Element?

Viewed 809

Visual Studio Code shows that target variable is of EventTarget type in the following TypeScript code:

document.addEventListener('click', (event) => {
  let target = event.target
})

Why isn't it marked rather as an Element? Can CharacterData or Document be also a target of MouseEvent? I was clicking in the web browser window with the following HTML code, but I was unable to obtain types of EventTarget other than Element.

<!DOCTYPE html>
<html>
<head>
 <title>Test</title>
 <script>
   document.addEventListener('click', (event) => {  
     let target = event.target
     console.log(target instanceof Element)
   })
 </script>
</head>
<body>
test
</body>
</html>

If Visual Studio Code marked target of MouseEvent as Element, then I would be able to write in Typescript:

document.addEventListener('click', (event) => {
  if (event.target.matches('.carousel__control--prev'))
    shiftCarouselLeft(event.target.closest('.carousel'))
})

But now I have to explicitly cast event.target to Element to call matches() function on it:

document.addEventListener('click', (event) => {
  let target = <Element>event.target
  if (target.matches('.carousel__control--prev'))
    shiftCarouselLeft(target.closest('.carousel'))
})
2 Answers

Any EventTarget can be the target of a MouseEvent event:

const foo = new EventTarget();
foo.addEventListener('click', (evt) => {
  console.log('is `foo`', evt.target === foo);
  console.log('is MouseEvent',  evt instanceof MouseEvent);
});
foo.dispatchEvent( new MouseEvent('click') );

It is possible to get mouse event on the whole Document node, but not for all events. You can get Document node for e.g. mouseenter and mouseleave as it's shown in the demo (works in Chrome, but doesn't work in Firefox or Safari).

It is also theoretically possible to get such event on text node, but AFAIK no browsers do it.

Related