0

I have some jQuery which animates the background colour of <div> tags when hovered (and reverts them when no longer hovered).

$('.row').hover(function() {
    $(this).stop().animate({
        backgroundColor: "#000000"
    }, 250 );
}, function () {
    $(this).stop().animate({
        backgroundColor: "#15181A"
    }, 250 );
});

And I have an AJAX call on my page to load some additional <div>s, like this:

$.ajax({
    type : 'POST',
    url : "ajax.php",
    dataType : 'json',
    data: {
        query : $('#search').val()
    },
    success : function(data) {
        if (data.error === true) {
            // Error
        } else {
            $('#more').html(data.msg);
        }
    },
    error : function(XMLHttpRequest, textStatus, errorThrown) {
        // Error
    }
});

The AJAX call effectively returns more <div>s with a class of "row", but when they're hovered the jQuery doesn't animate their background colour. Is it possible to select these rows with jQuery, even thought they were loaded via AJAX?

EDIT: Here's what's returned by the AJAX call, ajax.php:

<?php
$return['error'] = false;
$return['msg'] = '<div class="row" style="background: #15181A;">A row...</div>';
$return['msg'] = '<div class="row" style="background: #15181A;">Another row...</div>';
$return['msg'] = '<div class="row" style="background: #15181A;">Another row...</div>';
echo json_encode($return);
return;
?>
Ed Brissenden
  • 177
  • 2
  • 13

4 Answers4

3

Dynamic elements needs delegated event handlers :

$('#more').on({
    mouseenter: function() {
        $(this).stop().animate({
            backgroundColor: "#000000"
        }, 250 );
    },
    mouseleave: function() {
        $(this).stop().animate({
            backgroundColor: "#15181A"
        }, 250 );
    }
}, '.row');
adeneo
  • 312,895
  • 29
  • 395
  • 388
  • Thanks! This also answers my question, but I chose Ahren's answer as the best one because of your comment on it, saying it's the best way (without that I didn't know which was better of the two). – Ed Brissenden Mar 20 '13 at 01:47
  • @Edward - Uhm, well? I believe the answer I posted is the best way to do it, but both answers are the same in regards to event delegation, and that is the correct way to do it, I just used the events directly without having to check the type of event. – adeneo Mar 20 '13 at 02:00
  • @Edward - Yeah both do the same thing, so it comes down to readability and I would say this answer is a lot better in that regard - with the only downfall being the `context` param gets a little lost at the bottom. – ahren Mar 21 '13 at 05:22
  • I would vote up if I had the rep :( – Ed Brissenden Mar 21 '13 at 20:31
3

Bind it to your #more element.

$("#more").on("mouseenter mouseleave", ".row", function(e){
  if(e.type == "mouseenter"){ 
    // your hover code
  }else{
    // your off-hover code
  }
});
ahren
  • 16,803
  • 5
  • 50
  • 70
0

This is probably because you are calling your method to setup the hover effects prior to actually appending the page with your new content from your AJAX request.

For example somehting like this:

success: function (data) {
    if (data.error === true) {
        // Error
    } else {
        $('#more').html(data.msg);
        $('.row').hover(function () {
            $(this).stop().animate({
                backgroundColor: "#000000"
            }, 250);
        }, function () {
            $(this).stop().animate({
                backgroundColor: "#15181A"
            }, 250);
        });
    }

For when you append new elements that match the selector .row in the success of your AJAX request.

Sphvn
  • 5,247
  • 8
  • 39
  • 57
  • This will work but see @adeneo answer for better implementation. – Sphvn Mar 20 '13 at 01:32
  • And suddenly the existing elements with the same selector is bound twice, causing a range of errors ? – adeneo Mar 20 '13 at 01:33
  • I see no point in correcting my answer to be more "correct" when you already have hence my comment above. It's early in the morning here and I'm just not fast enough yet :P. However like I said this will work but is not a good implementation to solve the answer and your answer already provides that. – Sphvn Mar 20 '13 at 01:33
  • 1
    It's quite allright, as this is not always a bad solution, if you avoid binding elements multiple times etc. – adeneo Mar 20 '13 at 01:34
  • Also worth noting to people who do come to this page looking for information that might make this mistake of binding elements multiple times that a better way is as per your answer. – Sphvn Mar 20 '13 at 01:35
0

You need to recall the $('.row').hover(function() ... in your AJAX success function.

Steven
  • 303
  • 3
  • 11