Time to share another fun tip about Prototype.js — how to stop the default behavior of a link. Of course, I wasted hours of my life looking in all the wrong places to fix this problem, and now the time wasting will come to an end. But to appreciate my suffering, allow me to walk you through from the beginning.

In the simple days, we would add an event to a link, and stop the link from executing with this beauty:

link.onclick = function() {
    //do something
    return false;

And then we found out that an event listener is needed to attach more than one event to an object, so method 2 for attaching events became:

Event.observe(link, 'click', dosomething, false);function dosomething() {
    //do something
    return false;

The problem with this method is that return false; no longer works. The dosomething() function will not stop the link from going to the URL. So, a potential solution is seen in method 3:

 Event.observe(link, 'click', dosomething, false);
 link.onclick = function() {return false;};

Both functions will execute onclick, and a return false; is guaranteed. But this solution is not elegant. Luckily, Prototype.js offers method 4, which is Event.stop().

Event.observe(link, 'click', dosomething, false);function dosomething(e) {
    //do something

The above code will have the same functionality as return false;, and all the Event.stop() function needs as a parameter is the event. I was happy when Beau presented this solution to me, but my happiness was short-lived. This solution works in IE, Firefox, and the Safari Webkit, but it does not work in Safari 2.0.3. For now, I will have to keep using method 3 (unless someone knows a better way), but a good method is waiting to be used as soon as the next version of Safari comes out.

HTML Form Builder
Ryan Campbell

Event.stop() by Ryan Campbell

This entry was posted 5 years ago and was filed under Notebooks.
Comments are currently closed.


  1. Justin Perkins · 5 years ago

    I’ve always been frustrated by this, but I never really hear anybody talk about it, so I figured I was just dumb.

    I recently discovered Event.stop() and I fell in love, except I can’t get it to work properly with forms (when I’m observing the submit event).

  2. Ryan Campbell · 5 years ago

    I just assumed it would work with forms. I guess it is never that easy. I’ll play around with the form part and see if I can come up with anything.

    Off the top of my head, I think it me have to do with the event object e. If you try:


    Check and see what element it has a handle on. Sometimes with nested HTML it focuses on the first child (not sure why).

  3. Jordan Arentsen · 5 years ago

    I’m not sure where the correct place to put this. But what is your or ParticleTree’s take on JQuery. Is is better than prototype? Should it be used with Prototype. I’m just curious what your take is.

    Event.Stop looks nice.

  4. Ryan Campbell · 5 years ago

    Jordan - JQuery looks like it has some nice functionality, and the fact that it comes in around 10kb makes it appealing. The only thng I don’t like about it is the chainable function calls (I think they hurt readability), but you only have to use those if you want to. Right now, since I am so comfortable with Prototype and the features it has, I am not looking to switch. It is nice to keep an eye out for emerging libraries though, and JQuery may have some potential. The documentation is not finished, so I didn’t have time to go through the entire source looking at its capabilities.

  5. Justin · 5 years ago

    I’m a jackass Ryan, I forgot to pass in the event object, hence nothing would happen. Works like a champ.

    JQuery is amazingly small…but with more features in the DOM/Effects/Events world.

  6. Dustin Diaz · 5 years ago

    Ryan, starting to think you had something to do with the original prototype project. Did they hire you? ;)

    j/k man. Anyway, I like how you can do that with prototype. You’re slowly chipping away everything the library has to offer. This really is great.

  7. Ryan Campbell · 5 years ago

    Maybe in secret I wrote Prototype.

    Or maybe Ryan = Sam Stephenson!

    Or not :(

    But yeah, I’m tryin to chip.

  8. Daco · 5 years ago

    I found that anchorObj.removeAttribute (‘href’) works well in all browsers.

  9. Sylvain · 5 years ago

    This tip is really fun. Many thanks.

  10. Enrico Triolo · 5 years ago

    I’m not sure this solves your problem with safari, but I had some problems with firefox and found out that moving Event.stop(e) as the first command in the function resolved them!

    So, instead of having:

    function dosomething(e) { //do something Event.stop(e); }

    I now have:

    function dosomething(e) { Event.stop(e); //do something }

    Thanks for your article!

  11. Sunny Walker · 5 years ago

    I thought this information should have been basic material covered in the documentation. Thanks for taking care of that for us!

    I’m adding degradable ajax calls to some of my sites using the prototype library and found the following works well.


  12. Sunny Walker · 5 years ago

    Whoops, it looks like like my php was filtered out. Let me try again. :)

    Event.observe('delete-<?php echo $i; ?>','click',function(e){Event.stop(e);deleteWorkOrder('<?php echo $i; ?>');},false);

  13. Peter · 5 years ago

    Wow, this tip was really a life saver :) I used it as a workaround, because I can’t seem to get Event.observe working. Here’s a part of a code taken from a Class: registerCallbacks: function() { Event.observe(this.addLine,’onclick’, this.addline_onclick, true); }, addline_onclick: function() { alert(‘test’); },

    This doesn’t work, but this does: this.addline.onclick = this.addline_onclick.bindAsEventListener(this);

    And I really don’t get it :( With Event.stop I got rid of bubbling, which was causing the headaches.

  14. Tom Wright · 5 years ago

    I’ve been searching for this for ages!

  15. Rob Wilkerson · 5 years ago

    Here’s hoping someone’s still paying attention to this thread:

    Following up on Justin’s original question (that he appears to have found an answer for), I’m having the same problem and it’s starting to really frustrate me. I’d appreciate any help you might be able to throw my way.

    I have a form whose ‘submit’ event I’m listening for using prototype.js. On submit, I need to hash the password value before submitting. Unfortunately, the password is being hashed multiple times (I can’t say for certain how many). My code:

    Event.observe ( $( ‘profileLoginForm’ ), ‘submit’, function ( e ) { Event.element ( e ).profileLoginPassword.value = MD5 ( Event.element ( e ).profileLoginPassword.value ); // Event.stop ( e ); }, false );

    It’s clearly something I’m doing wrong. I get the same value every time, it’s just the same incorrect value. A little help and another set of eyes would be appreciated tremendously.

    Thank you.

  16. Rob Wilkerson · 5 years ago

    Oops. Sorry for the lousy formatting. Let’s try this:

    Event.observe ( $( ‘profileLoginForm’ ), ‘submit’, function ( e ) { Event.element ( e ).profileLoginPassword.value = MD5 ( Event.element ( e ).profileLoginPassword.value ); // Event.stop ( e ); }, false );

  17. Rob Wilkerson · 5 years ago

    I’m sorry about this guys, but Event.stop(e) is NOT commented out in my code. I’ve been trying every single thing I can think of and I happened to paste my last wildly flailing attempt. This is the “correct” code that I’ve tried and that has failed:

    Event.observe ( $( ‘profileLoginForm’ ), ‘submit’, function ( e ) { Event.element ( e ).profileLoginPassword.value = MD5 ( Event.element ( e ).profileLoginPassword.value ); Event.stop ( e ); }, false );

    Sorry for all of the confusion. My frustration is redlining right about now.

  18. Rob Wilkerson · 5 years ago

    It may be bad form, but I’m going to answer my own post so that:

    1. It may be useful to someone else, and
    2. Maybe someone can explain it to me :-)

    The key, I think, is in a portion of code I left out. Here’s the complete snippet that was NOT working:

    Event.observe ( window, ‘load’, init, false );

    function init() { Event.observe ( $( ‘profileLoginForm’ ), ‘submit’, function ( e ) { Event.element ( e ).profileLoginPassword.value = MD5 ( Event.element ( e ).profileLoginPassword.value ); }, false ); }

    And here’s what worked:

    Event.observe ( window, ‘load’, function ( e ) { Event.observe ( $( ‘profileLoginForm’ ), ‘submit’, function ( e ) { Event.element ( ev ).profileLoginPassword.value = MD5 ( Event.element ( e ).profileLoginPassword.value ); }, false ); Event.stop ( e );
    }, false );

    Can’t explain why. Certainly wish I could. The key seems to have been the window’s onload handler.

    You know, just in case anyone’s interested…

  19. Brendan Baldwin · 5 years ago

    Rob, my guess is that the reason that worked with the window ‘load’ is that your script is in an external file or otherwise runs before the form itself is instantiated. Waiting for the page to load means you’ll actually be reliably binding the event listener to the form, whereas running it before the form tags means you might be binding it to nothing.

  20. Webby · 5 years ago

    To fix this issue also in Safari you can use method 5: preventDefault ;)

    if (e && e.preventDefault) e.preventDefault(); //DOM return false; //IE

  21. Seb · 5 years ago

    Just wanted to point out that the comment above by Webby does not work.

    If you look int the Prototype code, the Event.stop actually calsl the event.preventDefault() method:

    Event.stop function if (event.preventDefault) { event.preventDefault(); event.stopPropagation(); } else { event.returnValue = false; event.cancelBubble = true; }

  22. Seb · 5 years ago

    Bah I used code instead of pre.

  23. Kurt · 4 years ago

    just a quick not about prototype.js… (this seems to work in most browsers EXCEPT Safari):

    You can gzip the prototype.js file, getting the filesize down to 12,479kb sweet! So I now include it with:


  24. Thomas · 4 years ago

    Thanks so much for that tipp

  25. Kumar Chetan · 4 years ago

    if(Ryan_needs_a_hug==1) Hug(Ryan); else return false; I guess if we simply return false on any action nothing will happen. Actually I learned it way back :P am just trying to show off. ;-) Good stuff. I msut work now. Rest of the stuff I will read later.

  26. www · 4 years ago

    Everyone needs a hug.w

  27. Andrew Hill · 4 years ago

    hi i am having trouble using this lightbox i have used the old one and it was fine but know i want to have a html file in my lightbox but once using this lightbox to do that i ge an error of: Method Not Allowed The requested method POST is not allowed for the URL /crowsnest/map.html. i not sure what this means but if anyone can help me it would be appreciated thank you Andrew the error is on the contact us page if you click the “click here for map” you will see what i am talking abt……..

  28. Jacek Pietrus · 3 years ago

    Thank you Ryan for that advice. It also works fine with anonymous function like this:

    tagA.each( function( n, i ) {
        Event.observe( n, 'click', function( e ) {
            tagDid.setStyle( { backgroundColor: 'red' } );
            Event.stop( e );
        }, false );
    } );
  29. tomo · 3 years ago

    Thank you soo much. This really should have been pointed put and put in a h1 tag on the prototype site.