1

I need to be able to detect any click that happens within a specific container referenced by class, if the user clicks on any of the nested elements I should be able to detect the click and update a flag

<div class="container" >
   <div class="x1">
   <div class="x2">
      <div class="">
         <span class="">
         <ul class="">
   </div>
</div>

I tried using jquery but I prefer to do it using backbone.

//$(document).on('click','.container', function(e){
//$('.container').delegate("div", "click", function(e) {

Not sure what event I need to use when the users are clicking in some of the nested elements within the div that have the container class. Basically, I need to update a flag in case of the user clicks outside of this div, but I don't want to have a large scope on the event handler that listens to the whole body.

Koitoer
  • 16,802
  • 7
  • 55
  • 79
  • Possible duplicate of [What is DOM Event delegation?](http://stackoverflow.com/questions/1687296/what-is-dom-event-delegation) – Makyen Oct 06 '16 at 00:45
  • Related: [Jquery live() vs delegate()](http://stackoverflow.com/q/4579117/3773011) – Makyen Oct 06 '16 at 00:48
  • 1
    `"I need to update a flag in case of the user clicks outside of this div"` - How would that be accomplished by detecting clicks *inside* the `div`? Can you elaborate on how your first attempt "didn't work"? That would indeed detect clicks inside the `div`. – David Oct 06 '16 at 00:48
  • it seems some of the components have an event stop propagation that I was not aware of, so I don't receive the event in the next handler – Koitoer Oct 06 '16 at 23:42

3 Answers3

3

Since you asked for a Backbone example, here's how to listen to clicks on a div and its children.

var View = Backbone.View.extend({
    className: "my-test-view",
    template: '<div class="container"><div class="x1"><div class="x2">test</div></div></div>',
    events: {
        'click .container': 'onClick',
    },

    render: function() {
        this.$el.empty().append(this.template);
        return this;
    },

    onClick: function(e) {
        console.log("clicked on", e.target, " triggered from ", e.currentTarget);
    },
});

var view = new View();

$("body").append(view.render().el);

Clicking the test text should output:

clicked on <div class=​"x2">​test​</div>​  triggered from  <div class=​"container">​…​</div>​

With jQuery, the above is (roughly) the equivalent to:

$('.my-test-view').on('click', '.container', function(e) {
    console.log("clicked on", e.target, " triggered from ", e.currentTarget);
});

But for most case, this should be enough:

$('.container').on('click', function(e) {
    console.log("clicked on", e.target, " triggered from ", e.currentTarget);
});

Don't use .children().on(...) as this will create a new listener for each child and it's inefficient.

Detecting a click outside a div is quite different and there are many ways to achieve it but none is perfect.

See :

Personally, I used focus and blur events (don't forget tabindex="-1" on the element).

Emile Bergeron
  • 14,368
  • 4
  • 66
  • 111
0

Maybe this?:

$(document).on('click','.container *', function(e){
console.log(e.target);
});

The great thing about jQuery is that you can use the same selectors as you would use with CSS hence I used .container * to target all elements inside the container.

Sergio Alen
  • 706
  • 5
  • 8
-2

I used the jquery .children() method. Check out this code pen.

var flag = 'whatever';

$(.container).children().on('click', function() {
  flag = 'updated';
});

Essentially, saying for all children of whatever element is class container (div in this case) add an event handler.