2

http://blog.jeremymartin.name/2008/02/building-your-first-jquery-plugin-that.html

Based on this tutorial, I created my first plugin and made some modifications. But, the plugin doesn't work for dynamically generated content when I load new content on the site.

I have no idea how to go about making it live. The events are already using .on but the building of the pluggin doesn't work.

Here is the jsFiddle: http://jsfiddle.net/bT4dH/13/

I know I could call the plugin everytime I add content dynamically, but as that gets messy very quickly, I would prefer to avoid it, and integrate it directly into the plugin.

I was starting to try this:

$(document).on('DOMNodeInserted', function (e) {
    if (e.target.classname === 'JS_postShrinker') {
         $(e.target).shrinker(options);
    }
});

But it doesn't work

UPDATE

Please ignore the DOMNodeInserted, I was just trying it. How do people in general make plugins live? I have the same problem with:

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
denislexic
  • 10,786
  • 23
  • 84
  • 128
  • 1
    You might prefer `$(e.target).is('.JS_postShrinker')` or `$(e.target).hasClass('JS_postShrinker')` in case it has multiple classes – Eric Sep 01 '12 at 14:13
  • Is there a way to get the called function class? For example, when I call the pluggin with $('.greatClassName').shrinker(). Inside the plugin, can I get the 'greatClassName' ? This would enable to make it much more DRY...Thanks. – denislexic Sep 01 '12 at 14:20
  • I would certainly not expect `$('.greatClassName').shrinker()` to modify things as they are inserted. That feels inherently wrong. I would prefer a more generic `$('.greatClassName').andFuture().shrinker()` or `$('.greatClassName').on('create', function() { $(this).shrinker(); })`. This is a job for a separate plugin, not for your shrinker plugin. – Eric Sep 01 '12 at 14:27

2 Answers2

3

You can simply make it live by using .on() in a bit different way, with delegation. The documentation explains it in detail.

$(closeParent).on(event, selectorForElement, handler);

All you have to do is to choose a parent that you surely know will be part of the DOM when you attach the handler. In the worst case, you can choose body.

Then you attach the handler on this element, and specify the selector for the child elements (that can be inserted into the DOM at any time). The handler will run whenever the event is fired on any of the child elements matching the selector. This method makes use of event bubbling in a very clever way.

EDIT: Of course this will only work for event handling. If you need to initialize your elements when they are added to the DOM (resizing, decorating, etc.), you better call the plugin every time this happens. This is how most plugins work. The DOMNodeInserted event is not cross-browser and deprecated, like all Mutation events, so you should not use it.

kapa
  • 77,694
  • 21
  • 158
  • 175
  • 2
    +1, although this won't solve everything, because his script needs to run some code to check the height, etc. that needs to run when the element is created - and there is no event for that (DOMNodeInserted is not cross-browser, slow and deprecated). – lqc Sep 01 '12 at 14:02
  • @lqc Thanks, added a note into my answer. – kapa Sep 01 '12 at 14:08
  • Thanks for the answer +1 for now. Do you know how I could get the plugin selector? For example, when I call the pluggin with $('.greatClassName').shrinker(). Inside the plugin, can I get the 'greatClassName' ? This would enable to make it much more DRY...Thanks. – denislexic Sep 01 '12 at 14:27
  • So there is no other way than calling it everytime (Don't want to use DOMNOdeInserted anymore, since it is deprecated)? Cause I'm using JSF (Java) to do all the AJAX requests, and it s a bit of a nightmare to do it that way, and plus it gets messy. Thanks. – denislexic Sep 01 '12 at 14:29
  • 1
    @denislexic About the selector: for example [this question](http://stackoverflow.com/questions/2420970/how-can-i-get-selector-from-jquery-object). About calling it everytime: it will not get messy if you write structured code on the client side. You can use Backbone.js, Spine, Javascript MVC, etc. – kapa Sep 01 '12 at 17:23
-1

There is an extra parameter (selector) to delegate the event on it:

$(document).on('DOMNodeInserted',"." + opts.clickZoneClass, function (e) {
    if (e.target.classname === 'JS_postShrinker') {
         $(e.target).shrinker(options);
    }
});
Samson
  • 2,801
  • 7
  • 37
  • 55