31

I'm building a web application that is extendable by dropping scripts into a preset directory. The script needs to read file headers before going to a page, so I need to use .preventDefault() when links are clicked and run some JScript first. Unfortunately I can't get past the .preventDefault()

Here's my link format:

<a href="path/to/file.php" class="filelink">Some Text</a>

here's the jquery I'm trying to use to stop the default action:

    $( '.filelink' ).click( function( e ) {
        e.preventDefault();
        //do some other stuff here
    });

EDIT:

More Info:

The <script>...</script> is in my footer. This function is INSIDE $(document).ready AFTER a $.ajax call that builds the list of links this function is trying to listen for clicks of.

KingRichard
  • 990
  • 2
  • 11
  • 24
  • 1
    you're missing a closing `)` in your jquery statement. the click event is never fired because of a syntax error. – r3wt Jan 09 '15 at 23:14
  • lol, was actually in there editing it when you commented. I just mistyped it on entering it here. it now looks exactly as it does in myscript, but is not firing. – KingRichard Jan 09 '15 at 23:16
  • I rolled back the edit because it wasn't clear yet that the typo was just in question or in actual code at the time of edit. As written, with the fixed typo, i see no reason for the problem you describe. – Kevin B Jan 09 '15 at 23:17
  • Where is the `` located? – Kevin B Jan 09 '15 at 23:21
  • see edits for further clarification – KingRichard Jan 09 '15 at 23:28
  • @RichardN see my answer below. – r3wt Jan 09 '15 at 23:31
  • 3
    Duplicate of [Event binding on dynamically created elements?](http://stackoverflow.com/q/203198/218196) (can't vote to close anymore, someone else please do it (@KevinB)). – Felix Kling Jan 09 '15 at 23:33
  • But this question ranks higher in Google.... what's up with all the close-voting... spend your time actually answering questions – Stijn de Witt Nov 06 '15 at 13:25

5 Answers5

82

Since your links are appended dynamically to the page, you need to use document.on() to capture the click events.

the syntax for appending event listeners to dynamic content is as follows

$(document).on( event, selector, callback );

so your click handler would become:

$(document).on('click','.filelink',function(e){

 e.preventDefault();

 //code here

 return false;

});
r3wt
  • 4,262
  • 2
  • 28
  • 52
  • Thanks for that. I didn't know this about dynamically appended elements. Do you know why this is? – KingRichard Jan 09 '15 at 23:35
  • 3
    because the element doesn't exist when you create the clickhandler, ie at the time dom loaded. jQuery doesn't listen for new elements in the selector list, it would be horribly innefficient and would crash on pages with dynamic content. – r3wt Jan 09 '15 at 23:35
  • 5
    the `return false` is not actually necessary. preventDefault() should be sufficient. – amenthes Jan 09 '15 at 23:36
  • @amenthes i was under the impression the event will continue bubbling up the stack unless you return false, and doing so allows gc to collect some trash. – r3wt Jan 09 '15 at 23:38
  • 4
    @RichardN: I recommend to read the [documentation](http://api.jquery.com/on/): *"Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to `.on()`."* – Felix Kling Jan 09 '15 at 23:38
  • 3
    @r3wt: You are right. `return false;` is equivalent to calling `event.preventDefault(); event.stopPropagation();`. – Felix Kling Jan 09 '15 at 23:39
  • 2
    @amenthes to add to r3wt's remark, actually the return false prevents the #hashtag hyperlink to be displayed on the address bar which sometimes is strictly unwanted. probably for this case it's unnecessary, but just adding two cents here :) – Amjo Oct 29 '17 at 16:00
  • @FelixKling One uses the container for the dynamic elements as the selector. That makes a "delegated event handler." From the docs: Delegated event handlers have the advantage that they can process events from descendant elements that are added to the document at a later time. Not sure when this was introduced. https://api.jquery.com/on/ – Bob Brown Dec 08 '20 at 22:54
6

I think you missed $(document).ready()

Please update your code as following:

$(document).ready(function(){
     $( '.filelink' ).click( function( e ) {
        e.preventDefault();
        //do some other stuff here
    });

})
Mouhamad Kawas
  • 340
  • 2
  • 12
3

is your code surrounded by:

$(function(){

//your code here

});

? or

$(document).ready(function(){

//your code here

});

? , because you should wait until the <a></a> element is ready before adding your click listener to it. try the code above or place your code at the bottom of the html right before the </body> tag or just right after the <a></a> element. that should work

EDIT: since your links are added dynamically call your $( '.filelink' ).click() function right after they are added

Santiago Hernández
  • 4,513
  • 1
  • 23
  • 33
0

I had the same problem, because I changed the window.location.search in my event handler:

 $( '.filelink' ).click( function( e ) {
        e.preventDefault();
       window.location.search = "something";
 });

To fix my problem I used window.location.hash (which is more what I wanted anyway).

arthur.sw
  • 9,516
  • 7
  • 34
  • 82
0

For me, the issue was a syntax error in the Javascript code.

I substituted a php variable to one of the JS variable like below,

var myvar = "<?php echo $myvar; ?>";

which produced the below result,

var myvar = "value in "myvar" which is not escaped";

It worked when I escaped the variable.

Please check if there is any syntax error in your code.

manian
  • 1,378
  • 2
  • 11
  • 27