0

Guys i have blog post list loaded with ajax that list append html in one div. That ajax html result have some buttons witch need to execute some js events on click. Problem is bcs that loaded html result wont detect some events...

With ajax i get full post list like below post-list.php but when i try to click on button like or dislike in that ajax result event is not fired idk whay all that functions is in one file. I check to inspect with firebug he only detect listPosts() function.

See example: In my index this result is loaded :

post-list.php file

<!-- List of post loaded from db (LOOP)
<h1>Post title</h1>
<p> Post content </p>
<button id="like">Like</button> <!-- jquery click event need to be fired but wont -->
<button id="dislike">Dislike</button> <!-- the some -->

Script example:

var Post = {

    addPost: function() {
        // Ajax req for insert new post
    }

    listPosts: function() {
        // Ajax req for fetching posts
    }

    likePost: function() {

        // example
        $("#like").click(function() {

            console.log("liked") // debug
            $.ajax() // etc;
        });

    dislikePost: function(obj) {
        // the some
    });

    init: functon() {
       Post.addPost();
       Post.listPosts();
       Post.likePost();
       Post.dislikePost();
    }
}

Post.init();

This script load all post with ajax, add new post on some event, send like result in db and dislike. So in this post list result when i try to click like or dislike button nothing is happening.

Only work if i do this:

<button id="like" onclick="Post.likePost(this);">Like</button>

But i dont want to do this in this way. I dont understand that script detect listPosts() but wont detect other functions in that ajax response.

Ivan
  • 5,139
  • 11
  • 53
  • 86

3 Answers3

1

I would recommend to use class name instead of duplicating same ids again and again:

<button class="like">Like</button> 
<button class="dislike">Dislike</button> 

Now you can delegate the event to the static parent element:

$('staticParent').on('click', '.like', Post.likePost)
                 .on('click', '.dislike', Post.dislikePost);

where $('staticParent') would be the container element which holds the buttons and it was there before posts load. Although you can replace it with $(document) too, but lookup from document could make event execution a bit slow.

Jai
  • 74,255
  • 12
  • 74
  • 103
1

Event bubbling.

Delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, you can use delegated events to avoid the need to frequently attach and remove event handlers. This element could be the container element of a view in a Model-View-Controller design, for example, or document if the event handler wants to monitor all bubbling events in the document. The document element is available in the head of the document before loading any other HTML, so it is safe to attach events there without waiting for the document to be ready.

$('#container-div').on('click', '#like', function() {
    console.log('Liked');
});

If you have a static container-div, it will have all events within it bubble up, i.e. it can see any events caused by dynamically created objects.

JBux
  • 1,394
  • 8
  • 17
-1

The solution to this problem would be to use "event delegation". This is a very powerful feature, and allows you to use event handlers without needing to explicitly attach them to an element or group of elements. This is an example:

$('#like').on('click',handleLike);

This would mean that anything matching the selector will have the callback fired. Also, I would recommend changing from using ids to something more generic, like CSS classes.

Rob Foley
  • 601
  • 4
  • 6