2

From the title this seems simple, but it's not as simple as the title.

I'm trying to detect instances of a div on a page with something like .live however live can only be applied to events such as click, mousedown, etc, there is no event such as domupdate or something.

Now let me explain what I'm doing. when I run the plugin it checks the dom for all instances of a div class (so for this example: c_talk is the class). Then for each of those returned elements it performs actions. I need this script for work for all divs on the page with the class c_talk even after a dom update via ajax or other means.

So when I run jQuery('div.c_talk').c_talk(); it should detect all instances in dom no matter what.

Here is the code so far


(function($){
$.fn.c_talk = function () {
    var fn = $.fn.c_talk;
    var opt = {
        divliveprev : 'view_prev',
        divlivesend : 'send'
    }
    // test function
    fn.activateLive = function($this) {

    }

    // do for each element in dom
    return this.each(function(e){

        var $this = jQuery(this);

        if(!jQuery(this).data('init')) {
            // on page set it
            jQuery(this).data('init', '1');

        }else {
            // is already on page
            alert($this.size());
        }
        return false;
    });

};
})(jQuery);

jQuery(document).ready(function(){

    jQuery('div.c_talk').c_talk();
});

More Info for those that don't understand: Basically it's a facebook like comment box. You have a div, that div contains comments, a view previous button, and a post button, I will need to do things for each instance of comment box. The key is I have to be able to detect new comment boxes being appended since my site runs on 100% ajax. This script would work fine if I just needed to detect comment boxes onload. It's not that simple in my case though, since the script has to be able to detect new comment boxes on the fly (via ajax).. Any ideas, my website is kalluna.com if it helps you understand this better.

kr1zmo
  • 837
  • 3
  • 13
  • 30
  • What event do you need to attach? `click`? – alex Mar 10 '11 at 04:56
  • There will be no event attached to the c_talk div, this div contains comments, when I run that plugin it must detect all instances of the
    and then later on I will be making it attach event listeners to a post button and view previous comments button, but it has to do this for each div even after an ajax update. This may not make since, but try to break it down. run plugin (detect all instances of container even after domupdate) -> each -> Comment Container - > attach listeners
    – kr1zmo Mar 10 '11 at 05:00
  • You could bind a custom even using bind and trigger it at the end of the ajax update : http://api.jquery.com/live (the last section) – JohnP Mar 10 '11 at 05:01
  • what exactly are you trying to do? – S L Mar 10 '11 at 05:02
  • Isn't like only for events like click, mouseover, etc. Is there anyway to update the dom for the .each function so it finds the newly added divs with the class c_talk – kr1zmo Mar 10 '11 at 05:04
  • @experimentX Basically it's a facebook like comment box. You have a div, that div contains comments, a view previous button, and a post button, I will need to do things for each instance of comment box. The key is I have to be able to detect new comment boxes being appended since my site runs on 100% ajax. This script would work fine if I just needed to detect comment boxes onload. It's not that simple in my case though, since the script has to be able to detect new comment boxes on the fly (via ajax).. Any ideas, my website is http://kalluna.com if it helps you understand this better. – kr1zmo Mar 10 '11 at 05:08
  • http://stackoverflow.com/questions/5241304/applying-jquery-live-to-the-to-dynamically-generated-elements/5241335#5241335 this should help you. check the upvoted answer. – S L Mar 10 '11 at 05:18
  • @experimentX, thanks for your help, however I solved it by simply doing this. jQuery(document).find('div.class').each(function(){ alert('test'); }); – kr1zmo Mar 10 '11 at 05:33

2 Answers2

2

You could track HTML changes in a similar way that the jQuery livequery plugin does. The livequery plugin wraps all of the jQuery DOM manipulation methods and when any of them are called, the wrapper method does something special (in your case call the c_talk function on all divs with the c_talk class) and then proxies back to the original function.

$.each('append', 'prepend', 'after', 'before', 'wrap', 'attr', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove', 'html', function(i, funcName) {

   // Short-circuit if the method doesn't exist
   if (!$.fn[funcName]) return;

   // Save a reference to the original method
   var old = $.fn[funcName];

   // Create a new method
   $.fn[funcName] = function() {

      // Call the original method
      var r = old.apply(this, arguments);

      //rerun the original function call
      $('div.c_talk').c_talk();

      // Return the original methods result
      return r;
   }
});

Displaying change of content through parent

Community
  • 1
  • 1
Adam Ayres
  • 8,732
  • 1
  • 32
  • 25
  • 1
    @kr1zmo In response to `why do I get c.apply is not a function when I use this?` that got put on the linked answer, I'm not sure where the `c.apply` came from, did you change the variable names from what I put in my example? I used `var old = $.fn[funcName]` and `var r = old.apply(this, arguments)`. – Adam Ayres Mar 10 '11 at 06:34
1

You would need to poll for that I believe.

// Consider a function to make this DRY - getDomLength()
var domItems  = $(document).find('*').length;

setInterval(function() {
    if (domItems != $(document).find('*').length) {
         domChanged();
    }
    domItems = $(document).find('*').length; 

}, 100);

jsFiddle.

Polling for changes is usually the only way something is done if no other better way is possible.

Remember, you can tell where an event originated from using this code (click() for example)...

$(document).click(function(event) {
   var element = event.target;
});
alex
  • 479,566
  • 201
  • 878
  • 984