Handle click outside element in LWC

Although I wasn't able to solve my above problem exactly as I posted it, I was able to solve it with a different approach.

I believe the issue I was having was locker service related. This is just a theory, but I believe since e.target in my scenario is a proxy, it can't be used to compare against other nodes within my DOM, even if they are within the same component.

I was able to work around this issue by restructuring my code a little bit so that I am not relying on DOM node comparison. Here is an example of the final code.

onNodeClick = () => {
  this._isOpen = true;

  //Timeout is to prevent the click from continuing and closing the element right away.
  //Just this slight delay of 0 is enough to stop propagation
  window.setTimeout(() => window.addEventListener('click', this.handleClose), 0);
}

handleClose = () => {
  this._isOpen = false;
  window.removeEventListener('click', this.handleClose);
}

You can't navigate outside your own template. That's one of the security features of LWC's shadow DOM. Instead, create a transparent, fixed div that covers the entire screen area, then react to that, instead:

<template>
  <div class="backdrop" onclick={closeModal}></div>
  <div class="content">... your content here ...</div>
</template>

.backdrop {
  position: fixed;
  z-index: 999;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
.content {
  z-index: 1000;
  /* anything else you need here */
}

For a complete example, look at Lightning Strike's Lookup component (written in Aura, but still applicable).