2

I have a set of divs that looks like this

<div class="videoThumbnail" data-videoid="4">
   <div class="video"><img src="some/Url" alt="video thumbnail preview"/></div>
   <div class="title">I'm a video</div>
   <div class="download"><span class="ui-icon ui-icon-arrowthickstop-1-s"></span></div>
</div>

Then I am binding an event to the videoThumbnail class. That function works fine and well but I now need to bind another event for when download is clicked. My two bind events look like this.

//Bind selecting a thumbnail to change the video
$( '.videoThumbnail' ).not( '.download' ).on( 'click', function ( t ) {
    alert('you are doing thumbnail stuff');
} );
//Bind download on the litle download icon
$( '.download' ).on( 'click', function ( t ) {
    alert('you want to download this');
} );

I would like the first bind event on videoThumbnail to only happen when it's not selecting the download within it. Unfortunately whenever i press the download icon both functions execute. How can I bind the first event to the videoThumbnail without binding it to the download that's inside of it?

rrk
  • 15,677
  • 4
  • 29
  • 45
WWZee
  • 494
  • 2
  • 8
  • 23
  • Stop event propagation for click event on .download – A. Wolff Jan 27 '16 at 18:01
  • 1
    since the first click function only applies to two elements you can also bind directly to them `$( '.videoThumbnail .video, .videoThumbnail .title' ).on( 'click', function ( t ) { alert('you are doing thumbnail stuff'); } );` – miguelmpn Jan 27 '16 at 18:06
  • @miguelmpn while that would work for this, I also have them in a for loop and there's 2 sets of them on the page, I thought that information irrelevant to the question though so I left it out. – WWZee Jan 27 '16 at 18:08
  • 1
    You can have different childs? but at least `.download` is always present? – miguelmpn Jan 27 '16 at 18:09
  • You're right, it would always be the same classes, so that too is a viable answer – WWZee Jan 27 '16 at 18:10

2 Answers2

3

You need to use event.stopPropagation

Code

$('.download').on('click', function(event){
   event.stopPropagation();
   // the click code..
});
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
1

Stopping propagtion will prevent the event from bubbling, thereby preventing any parent event listener from being notified of the event that was dispatched. This may have inadvertent side-effects resulting in other unintended events being suppressed.

A better approach is to check if event.target is the .download element or a descendant element of .download.

$('.videoThumbnail').on('click', function(event) {
  if (!$(event.target).closest('.download').length) {
    // clicked on ".videoThumbnail" and "event.target" is not ".download"
  }
});

Here is an example demonstrating that:

$('.videoThumbnail').on('click', function(event) {
  if (!$(event.target).closest('.download').length) {
    alert('clicked on ".videoThumbnail" and "event.target" is not ".download"');
  }
});


$('.download').on('click', function(event) {
  alert('clicked on the ".download" element');
});
.videoThumbnail { border: 1px solid; }
.download { background: #f00; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="videoThumbnail" data-videoid="4">
  <div class="video">
    <img src="some/Url" alt="video thumbnail preview" />
  </div>
  <div class="download"><span class="ui-icon ui-icon-arrowthickstop-1-s">download</span>
  </div>
</div>
Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
  • _Stopping propagtion will prevent any other events from being fired._ Huh? It will stop this click event from bubbling, but it won't affect any other events. – Evan Davis Jan 27 '16 at 18:05
  • 1
    @Mathletics Correct. I clarified by stating that it will prevent any parent event listener from being notified of the event that was fired. – Josh Crozier Jan 27 '16 at 18:18