Detect click inside/outside of element with single event handler

JavascriptJquery

Javascript Problem Overview


Suppose I have one div in my page. how to detect the user click on div content or outside of div content through JavaScript or JQuery. please help with small code snippet. thanks.

Edit: As commented in one of the answers below, I only want to attach an event handler to my body, and also want to know which element was clicked upon.

Javascript Solutions


Solution 1 - Javascript

Here's a one liner that doesn't require jquery using Node.contains:

// Get arbitrary element with id "my-element"
var myElementToCheckIfClicksAreInsideOf = document.querySelector('#my-element');
// Listen for click events on body
document.body.addEventListener('click', function (event) {
    if (myElementToCheckIfClicksAreInsideOf.contains(event.target)) {
        console.log('clicked inside');
    } else {
        console.log('clicked outside');
    }
});

If you're wondering about the edge case of checking if the click is on the element itself, Node.contains returns true for the element itself (e.g. element.contains(element) === true) so this snippet should always work.

Browser support seems to cover pretty much everything according to that MDN page as well.

Solution 2 - Javascript

Using jQuery:

$(function() {
  $("body").click(function(e) {
    if (e.target.id == "myDiv" || $(e.target).parents("#myDiv").length) {
      alert("Inside div");
    } else {
      alert("Outside div");
    }
  });
})

#myDiv {
  background: #ff0000;
  width: 25vw;
  height: 25vh;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="myDiv"></div>

Solution 3 - Javascript

Using jQuery, and assuming that you have <div id="foo">:

jQuery(function($){
  $('#foo').click(function(e){
    console.log( 'clicked on div' );
    e.stopPropagation(); // Prevent bubbling
  });
  $('body').click(function(e){
    console.log( 'clicked outside of div' );
  });
});

Edit: For a single handler:

jQuery(function($){
  $('body').click(function(e){
    var clickedOn = $(e.target);
    if (clickedOn.parents().andSelf().is('#foo')){
      console.log( "Clicked on", clickedOn[0], "inside the div" );
    }else{
      console.log( "Clicked outside the div" );
  });
});

Solution 4 - Javascript

Rather than using the jQuery .parents function (as suggested in the accepted answer), it's better to use .closest for this purpose. As explained in the jQuery api docs, .closest checks the element passed and all its parents, whereas .parents just checks the parents. Consequently, this works:

$(function() {
    $("body").click(function(e) {
        if ($(e.target).closest("#myDiv").length) {
            alert("Clicked inside #myDiv");
        } else { 
            alert("Clicked outside #myDiv");
        }
    });
})

Solution 5 - Javascript

What about this?

<style type="text/css">
div {border: 1px solid red; color: black; background-color: #9999DD;
width: 20em; height: 40em;}
</style>

<script type="text/javascript">
function sayLoc(e) {
  e = e || window.event;
  var tgt = e.target || e.srcElement;

  // Get top lef co-ords of div
  var divX = findPosX(tgt);
  var divY = findPosY(tgt);

  // Workout if page has been scrolled
  var pXo = getPXoffset();
  var pYo = getPYoffset();

  // Subtract div co-ords from event co-ords
  var clickX = e.clientX - divX + pXo;
  var clickY = e.clientY - divY + pYo;

  alert('Co-ords within div (x, y): ' + clickX + ', ' + clickY);
}

function findPosX(obj) {
  var curleft = 0;
  if (obj.offsetParent) {
    while (obj.offsetParent) {
      curleft += obj.offsetLeft;
      obj = obj.offsetParent;
    }
  } else if (obj.x) {
    curleft += obj.x;
  }
  return curleft;
}

function findPosY(obj) {
  var curtop = 0;
  if (obj.offsetParent) {
    while (obj.offsetParent) {
      curtop += obj.offsetTop;
      obj = obj.offsetParent;
    }
  } else if (obj.y) {
    curtop += obj.y;
  }
  return curtop;
}

function getPXoffset() {
  if (self.pageXOffset) {
    // all except Explorer
    return self.pageXOffset;
  } else if (
    document.documentElement &&
    document.documentElement.scrollTop
  ) {
    // Explorer 6 Strict
    return document.documentElement.scrollLeft;
  } else if (document.body) {
    // all other Explorers
    return document.body.scrollLeft;
  }
}

function getPYoffset() {
  if (self.pageYOffset) {
    // all except Explorer
    return self.pageYOffset;
  } else if (
    document.documentElement &&
    document.documentElement.scrollTop
  ) {
    // Explorer 6 Strict
    return document.documentElement.scrollTop;
  } else if (document.body) {
    // all other Explorers
    return document.body.scrollTop;
  }
}

</script>

<div onclick="sayLoc(event);"></div>

(from http://bytes.com/topic/javascript/answers/151689-detect-click-inside-div-mozilla, using the Google.)

Solution 6 - Javascript

This question can be answered with X and Y coordinates and without JQuery:

       var isPointerEventInsideElement = function (event, element) {
            var pos = {
                x: event.targetTouches ? event.targetTouches[0].pageX : event.pageX,
                y: event.targetTouches ? event.targetTouches[0].pageY : event.pageY
            };
            var rect = element.getBoundingClientRect();
            return  pos.x < rect.right && pos.x > rect.left && pos.y < rect.bottom && pos.y > rect.top;
        };

        document.querySelector('#my-element').addEventListener('click', function (event) {
           console.log(isPointerEventInsideElement(event, document.querySelector('#my-any-child-element')))
        });

Solution 7 - Javascript

In vanilla javaScript - in ES6

(() => {
    document.querySelector('.parent').addEventListener('click', event => {
        alert(event.target.classList.contains('child') ? 'Child element.' : 'Parent element.');
    });
})();

.parent {
    display: inline-block;
    padding: 45px;
    background: lightgreen;
}
.child {
    width: 120px;
    height:60px;
    background: teal;
}

<div class="parent">
    <div class="child"></div>
</div>

Solution 8 - Javascript

For bootstrap 4 this works for me.

$(document).on('click', function(e) {
    $('[data-toggle="popover"],[data-original-title]').each(function() {
        if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
            $(this).popover('hide')
        }
    });
});

working demo on jsfiddle link: https://jsfiddle.net/LabibMuhammadJamal/jys10nez/9/

Solution 9 - Javascript

If you want to add a click listener in chrome console, use this

document.querySelectorAll("label")[6].parentElement.onclick = () => {console.log('label clicked');}

Solution 10 - Javascript

Instead of using the body you could create a curtain with z-index of 100 (to pick a number) and give the inside element a higher z-index while all other elements have a lower z-index than the curtain.

See working example here: http://jsfiddle.net/Flandre/6JvFk/

jQuery:

$('#curtain').on("click", function(e) {
    
    $(this).hide();
    alert("clicked ouside of elements that stand out");
    
});

CSS:

.aboveCurtain
{
    z-index: 200; /* has to have a higher index than the curtain */
    position: relative;
    background-color: pink;
}

#curtain
{
    position: fixed;
    top: 0px;
    left: 0px;
    height: 100%;
    background-color: black;
    width: 100%;
    z-index:100;   
    opacity:0.5 /* change opacity to 0 to make it a true glass effect */
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThomasView Question on Stackoverflow
Solution 1 - JavascriptKhalilRavannaView Answer on Stackoverflow
Solution 2 - JavascriptamosriveraView Answer on Stackoverflow
Solution 3 - JavascriptPhrogzView Answer on Stackoverflow
Solution 4 - JavascriptRayOnAirView Answer on Stackoverflow
Solution 5 - JavascriptbuildsucceededView Answer on Stackoverflow
Solution 6 - JavascriptAlex NikulinView Answer on Stackoverflow
Solution 7 - JavascriptSanto BoldizarView Answer on Stackoverflow
Solution 8 - JavascriptLabib Muhammad JamalView Answer on Stackoverflow
Solution 9 - JavascriptrbansalView Answer on Stackoverflow
Solution 10 - JavascriptAndreView Answer on Stackoverflow