Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery .live() not working

Tags:

jquery

php

my actual problem is that .live() jQuery method is not working.

This si the code where i use it:

    jQuery.fn.sb_animateMenuItem = function()
    {
    var mousehoverColor = '#0089F7';
    var duration = 250;

    return this.each(function()
    {
        var originalColor = $(this).css('background-color');
        $(this).live('mouseover', function()
        {
            this.style.cursor = 'pointer';
            $(this).animate().stop();
            $(this).animate(
            {
                backgroundColor: mousehoverColor
            }, duration);
        });
        $(this).live('mouseout', function()
        {
            this.style.cursor = 'default';
            $(this).animate(
            {
                backgroundColor: originalColor
            }, duration);
        });
    });
};

This snipped is used i another page in this way:

<script type="text/javascript" src="ui/js/jquery-1.4.2.js"></script>
<script type="text/javascript" src="ui/js/jquery-ui-1.8.1.custom.min.js"></script>
<script type="text/javascript" src="ui/js/color.js"></script>
<script type="text/javascript" src="engine/js/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript" src="ui/js/ui.js"></script>
<script type="text/javascript">
    // UI effects
    $(document).ready(function()
    {
      $('button').sb_animateButton();
      $('input').sb_animateInput();
      $('.top_menu_item').sb_animateMenuItem();
      $('.top_menu_item_right').sb_animateMenuItem();
      $('.left_menu_item').sb_animateMenuItem();
    });
</script>

Since my site uses AJAX requests i used the .live method in the first snippet, but when i load the page the effects are not applied the the button/input... tags.

If i remove the .live method and use the 'normal' way, ui effects defined in the first snipped are applied but only the the elements loaded before any AJAX request. The elements loaded after the ajax request are not affected by first snippet (though they have the same selector).

Thanks for helping.

like image 773
siannone Avatar asked Jun 13 '10 10:06

siannone


2 Answers

In short, you can't use .live() like this, it has to follow a selector base of some sort, this is from the .live() docs:

DOM traversal methods are not fully supported for finding elements to send to .live(). Rather, the .live() method should always be called directly after a selector, as in the example above.

You're calling .live() on a jQuery object representing a particular DOM element, instead you need to get the .selector the plugins running on, if there is one, this isn't guaranteed of course, then use that for .live, like this:

 jQuery.fn.sb_animateMenuItem = function() {
    $(this.selector).live(.....)

If you think about it, how does .live() work? It listens for event to bubble, checks if the target matches a selector, and executes if so (and in a context, that's a whole other discussion)...if you did $(DOMElement).live(), what selector is it checking to see if it should execute?

I guess you could argue based on the internal element uuid this should work, but then again that's just a .bind(), which would be less wasteful, so .live() doesn't do anything like that.


Update: Because I was curious about the easiest way to implement this without repeating code, here's a version of your plugin that chooses .live() or .bind() dynamically, based on if there is a selector present for .live() to use:

jQuery.fn.sb_animateMenuItem = function() {
  var mousehoverColor = '#0089F7';
  var duration = 250;
  var method = this.selector ? jQuery.fn.live : jQuery.fn.bind;
  method.apply(this, ['mouseover', function() {
     if(!jQuery.data(this, 'oColor'))
         jQuery.data(this, 'oColor', jQuery(this).css('background-color'));
     jQuery(this).stop(true).animate({ backgroundColor:mousehoverColor }, duration);
  }]);
  method.apply(this, ['mouseout', function() {
    jQuery(this).animate({ backgroundColor:jQuery.data(this, 'oColor') }, duration);
  }]);
  return this.css('cursor', 'pointer');
};

You can view a working demo showing both here.

like image 88
Nick Craver Avatar answered Oct 01 '22 09:10

Nick Craver


you may use .DELEGATE() instead of .LIVE, .ON, .BIND

like

$("body").DELEGATE($(this),"click","myfunction")

OR

$("body").DELEGATE($(this),"click",function () {
///code here
} )
like image 29
Rameez SOOMRO Avatar answered Oct 01 '22 08:10

Rameez SOOMRO