-2

This thing is driving me nuts.

So I load some simple HTML via AJAX and once it's loaded on the DOM I do this.

$('#wrap a.link').click(function(e) {
    e.preventDefault();
    alert("asdasdad");
});

It simply does not prevent the link from navigating to the url in the href attribute.

My syntax seems right and I've made sure the element is in the DOM and that the function finds the a.link element.

$("#wrap a.link").each(function(key, value) {
    console.log("found a link"); // this shows up in the console
});

I have also tried using off() and stopImmediatePropagation() just in case some other event may be interfering, but nothing. I've also tried binding the event inside the each() loop with the same result.

What could be causing this behaviour?

Pier
  • 10,298
  • 17
  • 67
  • 113
  • Probably because this is asked a lot, even here. A google search for "event dynamic element jquery" even renders a SO result. I didn't downvote though, I don't mind duplicates that much. – vcanales Dec 18 '14 at 21:25
  • 1
    `once it's loaded on the DOM I do this` So if this statement is true, this is not a delegation issue. Or maybe you aren't using relevant ajax callback. Anyway, your code miss some context to understand what's going wrong, e.g, how do you call it??? – A. Wolff Dec 18 '14 at 21:26
  • `#wrap` is the in the DOM since the body loads, and as you can see from the `each()` the elements are found inside `#wrap` so I assume the loaded code is in the DOM. Am I wrong to assume that? – Pier Dec 18 '14 at 21:35
  • As we still don't know how/when you are calling it, no one can understand your question. You talk about ajax call but didn't have provided any relevant code regarding it – A. Wolff Dec 18 '14 at 21:37
  • It's a standard `$.ajax`. Can you answer my question? – Pier Dec 18 '14 at 21:40
  • @Pier I already answered it i think, you didn't provide enough context regarding your code so obviously you were doing something wrong in your debugging logic. `$("#wrap a.link").each(...);` calling it once elements in DOM BUT calling `$('#wrap a.link').click(...);` BEFORE, that's what seems the most obvious to me – A. Wolff Dec 18 '14 at 21:50

2 Answers2

8

Bind the events to the body for dynamic elements:

$('body').on('click','#wrap a.link',function(e) {
     e.preventDefault()
});
vcanales
  • 1,818
  • 16
  • 20
  • This works. It's the same answer as @PeterKA but you answered 1 minute before he did. Can you explain why it works? – Pier Dec 18 '14 at 21:24
  • 1
    It's not technically the same, but it has the same effect. It works because dynamic elements are not in the DOM when the JS is loaded; it's like trying to bind events to elements that don't exist. If you bind it to the body, jquery basically rebinds the event every time by looking on the body for the selector on the second parameter. – vcanales Dec 18 '14 at 21:28
  • I understand that, but the elements have been appended to an element that is in the DOM, and the `each` loop finds the elements in the DOM. – Pier Dec 18 '14 at 21:41
  • @Pier FYI I answered before devJunk. I'm not asking you to accept my answer though. – PeterKA Dec 18 '14 at 21:41
  • @PeterKA oh you are right, I messed up with the time. – Pier Dec 18 '14 at 21:44
6

Use event delegation:

$(document).on('click', '#wrap a.link', function(e) {
    e.preventDefault();
    alert("asdasdad");
});

Caution: Keep your IDs unique.

PeterKA
  • 24,158
  • 5
  • 26
  • 48
  • 2
    Plus this way you don't have to wait for content to be loaded; you can do this whether the element is in the DOM or not. – Pointy Dec 18 '14 at 21:19
  • OP said: `once it's loaded on the DOM I do this` Not sure what's going on then. EDIT: just saw other question OP's comment, so it was wrong statement in question – A. Wolff Dec 18 '14 at 21:29
  • If it's loaded through ajax it's simply not loaded on the DOM beforehand. – vcanales Dec 18 '14 at 21:30
  • @devJunk I was guessing OP was talking about specific links, obviously not – A. Wolff Dec 18 '14 at 21:31