javascript - How to trigger event on arbitrary function call using jQuery - Stack Overflow

I'm wondering if it's possible to use jQuery's bind() to fire a custom event when an arb

I'm wondering if it's possible to use jQuery's bind() to fire a custom event when an arbitrary function is called. Something like,

/* when cmsPlugin.func() is called, fire myCustom.func() too */
$.bind( cmsPlugin.func, myCustom.func );

We're using the Lightbox2 plugin for Drupal on a site.

When the lightbox is displayed, I want to fire some custom code which will attach to clicks on a "download" link in the Lightbox.

The Lightbox2 plugin doesn't appear to call $.trigger(), so I have a few options -

  • Find a way to bind to javascript function calls. (In this case, Lightbox.end I believe.)
  • Use an existing event, eg $(document).ready, which may (?) be fired as part of the lightbox display.
  • Extend the existing function to add a $.trigger() call.
  • Just hammer myCustom.func() repeatedly for a time after detecting that a lightbox-triggering element has been clicked. (Ewww.)
  • ________ ?

Solution

I attempted to simplify my question by using the cmsPlugin.func / myPlugin.func but I think I might have confused myself in doing so. However, I hope that the solutions posted will be generic enough for future readers to use themselves.

Thanks Adam and Lucho. I didn't have any luck with Lucho's suggestion, but I suspect that this was my own fault and not Lucho's :)

At first I tried Lucho's example code, modifying it to fire Drupal.zipcart.init() when Lightbox.updateNav was executed. This didn't work for me.

I decided on Lightbox.updateNav() to extend because it was a simple function called late in Lightbox2's display method.

My attempt at modifying Lucho's code looked like this, but didn't work -

// NOT THE RIGHT SOLUTION (for me)
Lightbox.updateNav = function(_dz, _lb) { return function() {
        _lb.updateNav();
        _dz.init();
    };
}(Drupal.zipcart, Lightbox);

Here's the code I ended up using based on Adam's answer, which allows Drupal's ZipCart and Lightbox2 modules to play nicely together, making links with class="zipcart" in the lightbox correctly add files to the download cart.

(function(){
  var _updateNav = Lightbox.updateNav;
  Lightbox.updateNav = function () {
    $(document).bind('lightbox.updateNav', function() {
      Drupal.zipcart.init();
    });
    $("#lightbox").trigger('lightbox.updateNav');
    _updateNav.apply(this, arguments);
  }
})();
$(document).bind('lightbox.updateNav', function () { Drupal.zipcart.init(); });

I'm wondering if it's possible to use jQuery's bind() to fire a custom event when an arbitrary function is called. Something like,

/* when cmsPlugin.func() is called, fire myCustom.func() too */
$.bind( cmsPlugin.func, myCustom.func );

We're using the Lightbox2 plugin for Drupal on a site.

When the lightbox is displayed, I want to fire some custom code which will attach to clicks on a "download" link in the Lightbox.

The Lightbox2 plugin doesn't appear to call $.trigger(), so I have a few options -

  • Find a way to bind to javascript function calls. (In this case, Lightbox.end I believe.)
  • Use an existing event, eg $(document).ready, which may (?) be fired as part of the lightbox display.
  • Extend the existing function to add a $.trigger() call.
  • Just hammer myCustom.func() repeatedly for a time after detecting that a lightbox-triggering element has been clicked. (Ewww.)
  • ________ ?

Solution

I attempted to simplify my question by using the cmsPlugin.func / myPlugin.func but I think I might have confused myself in doing so. However, I hope that the solutions posted will be generic enough for future readers to use themselves.

Thanks Adam and Lucho. I didn't have any luck with Lucho's suggestion, but I suspect that this was my own fault and not Lucho's :)

At first I tried Lucho's example code, modifying it to fire Drupal.zipcart.init() when Lightbox.updateNav was executed. This didn't work for me.

I decided on Lightbox.updateNav() to extend because it was a simple function called late in Lightbox2's display method.

My attempt at modifying Lucho's code looked like this, but didn't work -

// NOT THE RIGHT SOLUTION (for me)
Lightbox.updateNav = function(_dz, _lb) { return function() {
        _lb.updateNav();
        _dz.init();
    };
}(Drupal.zipcart, Lightbox);

Here's the code I ended up using based on Adam's answer, which allows Drupal's ZipCart and Lightbox2 modules to play nicely together, making links with class="zipcart" in the lightbox correctly add files to the download cart.

(function(){
  var _updateNav = Lightbox.updateNav;
  Lightbox.updateNav = function () {
    $(document).bind('lightbox.updateNav', function() {
      Drupal.zipcart.init();
    });
    $("#lightbox").trigger('lightbox.updateNav');
    _updateNav.apply(this, arguments);
  }
})();
$(document).bind('lightbox.updateNav', function () { Drupal.zipcart.init(); });
Share Improve this question edited Oct 27, 2010 at 21:54 Chris Burgess asked Oct 27, 2010 at 19:53 Chris BurgessChris Burgess 3,6313 gold badges32 silver badges43 bronze badges 4
  • The bind call should be moved elsewhere, to separate the concerns between the updateNav function and your listener. I would also remend using delegate instead because the lightbox markup won't exist at page load. $(document).delegate('#lightbox', 'lightbox.updateNav', function () {}) will work regardless of how many times the lightbox markup is created or destroyed. Again, I don't know enough about the plugin to tell you exact how to select its markup. – Adam Lassek Commented Oct 27, 2010 at 21:25
  • Thanks, will look into delegate as well, although I see it's a recent addition to jQuery. I had spotted that the bind was in the wrong place. Might try live instead. – Chris Burgess Commented Oct 27, 2010 at 21:40
  • I don't need to bind to the specific #lightbox element, so I just associated the custom event with document instead. Code above updated; initially I had a $().bind() sitting inside the rewritten Lightbox.updateNav function. – Chris Burgess Commented Oct 27, 2010 at 21:47
  • If the lightbox markup is added to a particular section of your page, it would be better to attach the delegate to that -- attaching to document will work but the event has to bubble all the way to the top of the DOM before it gets triggered, so it will be slower. – Adam Lassek Commented Oct 28, 2010 at 0:46
Add a ment  | 

2 Answers 2

Reset to default 3

You cannot bind event listeners to a function. Events are bound and triggered from DOM nodes, so you need to know how to select the lightbox's markup. jQuery allows doing this now, but you still need a wrapper to trigger the event.

The cleanest way I can think of to acplish this would be to wrap the Lightbox.updateNav function and fire a custom event.

(function(){
  var _updateNav = Lightbox.updateNav;

  Lightbox.updateNav = function () {
    $("#lightbox").trigger('lightbox.updateNav');
    _updateNav.apply(this, arguments);
  }
})();

#lightbox needs to point to the lightbox markup that you can bind event listeners to. I don't know enough about LightBox2's API to tell you how to do this exactly.

This is better than a simple wrapper function because you can wire up as many listeners as you like.

$("#lightbox").bind('lightbox.updateNav', function() {})

Since the lightbox markup is likely created and destroyed dynamically, you would be better off using delegate instead (provided you have access to jQuery 1.4.2). If you can identify where the markup is inserted, attach a delegate to the parent element:

$('#lightbox-parent').delegate('#lightbox', 'lightbox.updateNav', function() {})

This is much better performance than .live() so I would remend doing it this way if you can.

cmsPlugin.func = function(myCustom, cmsPlugin) { return function() {
        cmsPlugin.func();
        myCustom.func();
    };
}(myCustom, cmsPlugin);

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745433244a4627490.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信