3

I am trying to implement a link inside of a DIV block which has a click event.

I would like the outer DIV click event not to run if the users clicks on the link.

My link looks like:

<a href="javascript: openVideo('videoID', this, event); " >Watch the video</a>

And JavaScript looks like:

 function openVideo(video, object, event) {
 
    $(object).html($(object).html()+"<iframe width='360' height='315' src='http://www.youtube.com/embed/"+video+"' frameborder='0' allowfullscreen></iframe>");
 
    event.stopPropagation();
 }

Unfortunately when I click on the link it executes the outer DIV code, and shows an error related to stopPropagation method:

Uncaught TypeError: Cannot call method 'stopPropagation' of undefined

What could be the issue?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Arturs Vancans
  • 4,531
  • 14
  • 47
  • 76

4 Answers4

6

Because there's no event being called. Try calling it like this instead:

<a href="#" onclick="openVideo('videoID', this, event); " >Watch the video</a>

j08691
  • 204,283
  • 31
  • 260
  • 272
  • This works perfectly! So when I write a query in the href it does not count as a click event? – Arturs Vancans Jun 25 '12 at 19:01
  • @Arturs I think you still need to do `return false;` to prevent the browser from scrolling to the top of the page when it is clicked. – sparebytes Jun 25 '12 at 19:05
  • @Kranklin can I just add javascript: void(); in the href part? – Arturs Vancans Jun 25 '12 at 19:06
  • @Arturs - a click on the link triggers the click event but you weren't capturing it properly. – j08691 Jun 25 '12 at 19:06
  • It doesn't seem to be working on IE. I am getting SCRIPT438: Object doesn't support property or method 'stopPropagation' – Arturs Vancans Jun 25 '12 at 19:17
  • stopPropagation() is only supported in IE9 and above. See http://stackoverflow.com/questions/387736/how-to-stop-event-propagation-with-inline-onclick-attribute for a discussion of stopPropagation and IE. – j08691 Jun 25 '12 at 19:19
1

I see you're using jQuery. It's not meant to be used in that manner. The event object you are passing is the browser's native event object. jQuery's event object provides a stopPropagation function.

To use jQuery appropriately, you must let jQuery bind the event instead of doing it inline.

<a href="#" class="openVideo" data-video="videoID" >Watch the video</a>

<script type='text/javascript'>
    $(document).ready(function() {
        $(".openVideo").click(function(ev) {
            ev.preventDefault();
            ev.stopPropagation();
            var videoID = $(this).data('video');
            $(this).append("<iframe width='360' height='315' src='http://www.youtube.com/embed/"+videoID+"' frameborder='0' allowfullscreen></iframe>");
        });
    });
</script>

Edit: with jQuery 1.4.3 or above you can use a delegate so you don't have to attach the event directly to the anchor but to one of its ancestors. (jQuery 1.7 uses the .on method to achieve the same thing). Here is an example using jQuery 1.7: http://jsfiddle.net/Tu9Hm/

<a href="#" class="openVideo" data-video="videoID" >Watch the video</a>

<script type='text/javascript'>
    $(document).ready(function() {
        $(document).on('click', '.openVideo', function(ev) {
            ev.preventDefault();
            ev.stopPropagation();
            var videoID = $(this).data('video');
            $(this).append("<iframe width='360' height='315' src='http://www.youtube.com/embed/"+videoID+"' frameborder='0' allowfullscreen></iframe>");
        });
    });
</script>

You pay a small performance penalty using delegates, so try to place the event on the lowest possible element in the DOM. Also, if you place the delegate on the document, you can't really stopPropagation since it has already reached the top, although I believe you're really more concerned about preventDefault()

sparebytes
  • 12,546
  • 3
  • 21
  • 32
  • That's what I thought too (that you need jQuery for `stopPropagation`), but it actually isn't the case. – Dan Tao Jun 25 '12 at 19:05
  • @DanTao I know Chrome supports it but IE may not. – sparebytes Jun 25 '12 at 19:07
  • I like your solution. The only issue is that my data (links) is loaded by ajax from different urls, so then I would need to add this code to every url I have links in. As if I run it only once when the main page loading is ready, it won't run again when small ajax data is received and therefore won't execute the code if I click on the new data. – Arturs Vancans Jun 25 '12 at 19:32
  • @Arturs, You can still make use of jQuery delegates where instead of attaching the listener directly to the anchor, you attach it higher up in the DOM where it is safe from being manipulated. You won't need to bind any listeners to any new anchor elements. – sparebytes Jun 25 '12 at 19:50
  • @Arturs, I updated the answer to use a delegate. Beware the code is untested. – sparebytes Jun 25 '12 at 19:55
  • @Arturs, One last thing, you should add `if($(this).children('iframe').size()) return` so that if the link is clicked multiple times there will still only be 1 iframe. – sparebytes Jun 25 '12 at 20:09
0

Edit: I lied; stopPropagation is not a jQuery exclusive. Go with j08691's answer.

As far as I know stopPropagation is a jQuery function, which means you'd need the event object created by a jQuery event handler to call it.

Here's one way:

<a id="open-video-link" href="javascript: void(0);">Watch the video</a>

<script type="text/javascript">
  $("#open-video-link").click(function(event) {
    openVideo("videoID", this, event);
  });
</script>

Take what I just wrote with a grain of salt, of course, because I'm going off of hazy knowledge and didn't look it up at all.

Community
  • 1
  • 1
Dan Tao
  • 125,917
  • 54
  • 300
  • 447
-2

Try

 $("a").on("click", function (e) {
            e.stopPropagation ();
        });
Ajay Beniwal
  • 18,857
  • 9
  • 81
  • 99