0

So I'm currently using .append() to add a feature to all of the posts on a webpage, but when additional posts are loaded on the page, the appended features aren't included in the new content — I'm trying to come up with a way to make sure all of the new content has the appended feature too.

$(this).append('<div id="new_feature></div>');

Something like this?

$(this).live().append('<div id="new_feature></div>');

Maybe there's a way to make it constantly appending in a loop perhaps?

Lil' Bits
  • 898
  • 2
  • 9
  • 24
  • 2
    Are you aware that you have spelled append wrong in your code? – Alex W Jan 12 '13 at 03:07
  • 1
    This is not how `.live` works ([check the documentation](http://api.jquery.com/live/)). Whenever you load new posts you have to add the features to them. – Felix Kling Jan 12 '13 at 03:08

6 Answers6

3

There is DOMNodeInserted event:

$('button').click(function() {
  $('#appendme').append($('<div class="inner">').text(Math.random()));

})

$('#appendme').on('DOMNodeInserted','.inner',function() {
 console.log(this); 
});

DEMO

update: this seems not works in IE, try propertychnage event handler also ($('#appendme').on('DOMNodeInserted,propertychange') but i not sure, have no IE to check this right now.

update2: Domnode* seems deprecated according to mdn, they tell to use MutationObserver object instead

update3: seems here is no very crossbrowser solution for MutationEvents, see this answer, so my suggestion would be use code above, if event supported and fallback to setTimeOut or livequery option.

update4: If you depend only on .append() you can patch jQuery.fn.append() like this:

jQuery.fn.append=function() {
                return this.domManip(arguments, true, function( elem ) {
                        if ( this.nodeType === 1 || this.nodeType === 11 ) {
                                this.appendChild( elem );                             
                                $(elem).trigger('appended');
                        }
                });
        };

$('button').click(function() {
  $('#appendme').append($('<div class="inner">').text(Math.random()));

})

$('#appendme').on('appended','.inner',function() {
 console.log(this); 
});

DEMO2

may be more correct is to spoof jQuery.fn.domManip like here

Community
  • 1
  • 1
zb'
  • 8,071
  • 4
  • 41
  • 68
  • Deprecated, not removed; and there is no place for it to go yet as DOM4 is still a WD. The bigger issue with MutationEvents is the support, and possibly lack-thereof. I have no idea which browsers implement it and to which extent. I wouldn't be surprised if there were some shim libraries .. –  Jan 12 '13 at 04:04
  • @pst I add some jquery native examples,what you can say about such way ? – zb' Jan 12 '13 at 05:12
2

jQuery documentation:

Use of the .live() method is no longer recommended since later versions of jQuery offer better methods that do not have its drawbacks.

You can use setTimeout() function that can check for new <div>s every n milliseconds.

$(function(){
    setInterval("Check4NewDivs();",1000);
});

So say this is a div with class="comment newdiv", so when it appears on the page for the first time, it has the class newdiv that will let the function know it was just dynamically created.

function Check4NewDivs(){
    $(".comment .newdiv").each(function(){
        $(this).append('<div class="new_feature"></div>').removeClass("newdiv");
    });
}
Lil' Bits
  • 898
  • 2
  • 9
  • 24
  • I tried implementing this — what's happening now is that I'm getting multiple copies of the new feature being rapidly adding over and over again to each post. –  Jan 12 '13 at 03:22
  • You must add something that lets JS know it's a newly formed `
    `. This is why I said if you have it so when a new `
    ` appears, it has the class `newdiv`, this will only effect the dynamically created `
    `s. Otherwise if you just leave it as `$(".comment")`, yes it will keep adding the 'new_feature' div.
    – Lil' Bits Jan 12 '13 at 17:26
  • Also `
    `. All `id` attributes should be unique.
    – Lil' Bits Jan 12 '13 at 17:27
1

It's append not appened.
live is a deprecated event handler. It's not used this way. use on instead. http://api.jquery.com/live/

So, the following code will run when you click selector.

$(document).on('click', 'selector', function() {
    $(this).append('<div id="new_feature></div>');
});
Ricardo Alvaro Lohmann
  • 26,031
  • 7
  • 82
  • 82
1

No, there is no standard way to do it like that. There was a proposal of the events that would be fired whenever the DOM elements are inserted etc., but you cannot rely on that.

Instead rely on either:

  • (preferably) callbacks - just invoke function ensuring existence of such appended snippets, whenever you pull something (but after you successfully pull it from server and insert into DOM, not sooner), or
  • constant checks - like using in setInterval() or setTimeout(), but this would be unnecessary processing and you will never get instant append, unless you will perform processing-heavy checks all the time,
Tadeck
  • 132,510
  • 28
  • 152
  • 198
  • Ref: [MutationEvents from DOM2](http://www.w3.org/TR/DOM-Level-3-Events/#events-mutationevents), deprecated by [MutationObservers in DOM4](http://www.w3.org/TR/dom/#mutation-observers) –  Jan 12 '13 at 03:13
  • So I should use setTimeout() to rapidly check for new content to append to? –  Jan 12 '13 at 03:16
  • @luke Only as a *last* effort (e.g. user modifications or modified by third-party code). If the DOM manipulation is controlled by you - e.g. from AJAX - then there is no need. –  Jan 12 '13 at 03:28
0

use the on load function:

$(item).on('load',function(){
    $(this).append('<div id="new_feature"></div>');
});

This will add append the item as a callback once the item has been loaded. I would also choose some sort of dynamic ID creator rather than always append stuff with the same ID, but thats just me.

PlantTheIdea
  • 16,061
  • 5
  • 35
  • 40
  • That works only if there is something to load, not when you append a text for example. – Tadeck Jan 12 '13 at 03:09
  • aren't new posts the items being loaded? – PlantTheIdea Jan 12 '13 at 03:10
  • @TonyQuentano: Please read [jQuery's documentation on `load` event](http://api.jquery.com/load-event/), especially this part: "_The load event is sent to an element when it and all sub-elements have been completely loaded. This event can be sent to any element associated with a URL: images, scripts, frames, iframes, and the window object._". No, text-only posts are not something that is being _loaded_ in terms of `load` event. You load only something that has the URL (image, script, frame etc.). – Tadeck Jan 12 '13 at 03:13
0

you must bind to an element that already exists on the page. i have written an example where i make appended content live.

DEMO on JSFiddle

HTML

<div id="container">
  <div id="features">
  </div>
  <br />
  <a href='#' id='clickme'>click me to add feature</a>
</div>

JS

$(function() {
  $('#clickme').on('click', function(e) {
    $('#features').append('<div class="new_feature">new feature</div>');
  });

  $('#features').on('click', '.new_feature', function() {
    alert('i am live.');
  });
});
Sean M
  • 1,990
  • 20
  • 16