1

I have been trying to find a way to detect every time the count of a particular object has changed in the DOM.

For example, assume class '.special' currently returns 5 objects:

$('.special').css('color','1px solid red');

Later on in time, the user results in the number of .special objects to increase or decrease. So, as soon as the number of .special objects changes from 5, I would like an event to trigger.

Is this possible?

I tried using the change event for this, but it will not work in this instance.

Many thanks in advance!

AnchovyLegend
  • 12,139
  • 38
  • 147
  • 231

5 Answers5

1

You can capture the DOMNodeInserted event.

document.addEventListener('DOMNodeInserted', function(e){
    alert($('.special').length);
});

The problem is, this event is not supported by IE8 and before.

Maybe you can find a workaround but I haven't tried.

Here's a JSFiddle that works.

Community
  • 1
  • 1
thitemple
  • 5,833
  • 4
  • 42
  • 67
0

With your situation (there are 20 different ways a user can decrease or increase the count of elements in the DOM) one thing only comes to my mind. You should store your current special elements and could use a setInterval and try to call a function for example every 2 seconds and check the specials count and compare it to the previous number. If they are not equal, then there's a change. And i would not suggest this method and i think it's better to put a click binding on all your different ways.

MIIB
  • 1,849
  • 10
  • 21
0

The simplest way to solve this issue is to make a proxy method that creates ".special" objects. You need the event of creation to control the current number of elements in DOM, so, for example:

function createNewSpecial() {
    var specialCnt = $('.special').length;
    if (specialCnt > 5) {
        // magic
    }

    // creation of another ".special" element in DOM if needed
}
Stormherz
  • 376
  • 2
  • 11
  • 1
    He mentioned that there are 20 different ways to increase or decrease the special objects. That's the problem – MIIB Mar 05 '13 at 19:16
0

The best solution would be to define a function that performs the operation you wish to happen on addition of a column, in example:

function on_add_column() {
  // do stuff
}

Now bind this function to all events that are causing the addition of a column, like clicks, ajaxs or what have you.

$("button#add").on("click", on_add_column)
$("a#add-link").on("click", on_add_column)
$("input#beh").on("change", on_add_column)

Using a timeout would mean having jQuery query the DOM on a set interval... which is not efficient. Also, you should know all of the actions that will cause the addition of a column within your own application.

Austin
  • 6,026
  • 2
  • 24
  • 24
0

Ok, this does involve some code but custom events might work. Here I have a custom "specialEvent" that I fire, and a "trackChanges" function to do what you will.

I created a "tracker" function in a fiddle that simply adds a class depending on what changed here: http://jsfiddle.net/DsSQd/1/ and keeps track of the length previously seen in a "tracker" element - in this case the parent of the group. It is a bit ugly, but you can do what you want there, in mine, I track the length of the group in the parent wrapper and simply add a class depending on whether the length changed or not, and if not, just highlight the element that fires the event.

// custom event handler
$(document).on('specialEvent', '.special, .changerthing, .friendly>.specialalso', function () {
    trackChanges(this, $(this).parent(), $(this).parent());//react to the change
});
// event where I trigger the handler
$('#wrapperToBindTo').on('click wacked', '.changers,.special,.changerthing', function () {
    $(this).trigger('specialEvent');
});
// event where I trigger the handler
$('.friendly').on('click', '.specialalso', function () {
    var me = $(this);
    me.clone().appendTo($(this).parent()).text(me.text() + ' Copy of:' + me.index()); //add one
    me.parent().find('.specialalso:last').trigger('specialEvent'); //fire special event
});

For example, we could then add this function:

//added to show a remove, then trigger that cascades
$('#wackFriendly').click(function(){
    $('.friendly>.specialalso').last().remove();
    $('.friendly>.specialalso').last().trigger('wacked');
});

and then handle that as seen here: http://jsfiddle.net/DsSQd/2/

Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100