Chris Kempen
Chris Kempen

Reputation: 9661

Adding custom CSS classes to dynamically-created elements with jQuery

Let me illustrate my question: I have an external JavaScript library that creates certain HTML elements for me dynamically based on user input and interaction, and I'm looking to write a script that would automatically add a certain class to these dynamically created elements. Assume that I also am unable to edit the external JavaScript library I'm using.

Is this elegantly possible? If so, how? If not, could this be a side-effect of poor implementation design?

I've thought about somehow monitoring the DOM to see when it was updated, and adding the classes to these new elements then, but this seems cumbersome and possibly unnecessary.

Thanks in advance for any thoughts / solutions!

Edit:

As requested, here's a simplified example of what I'm trying to accomplish with a code sample:

// function in external library, assume it cannot be edited!
function addElement() {
    $('body').append($('<div class="newly_created_element"></div>'));
}

// my code, looking to add the class name to the newly-created elements
// from the external function above...
// pseudo-coded as I have no idea how to do this!
$(function(){
    when (new element added) {
        add class "my_own_class";
    }
});

I hope this makes sense!

Upvotes: 5

Views: 31022

Answers (6)

manish
manish

Reputation: 1

This works fo me, I keep on checking wether that class exists or not ,once it finds it ,the interval function stops

var interval=setInterval(function(){ 
    if($('._icon').children().hasClass('_share')){
      clearInterval(interval);
    }else $('._icon').children().addClass('_share');
}, 1000);

Upvotes: -5

Chris Kempen
Chris Kempen

Reputation: 9661

For the sake of thoroughness and bringing a clear solution to my question to light, herewith my conclusion. Thank you all for your thoughts and suggestions, I've learnt a lot and clearly got people thinking!

Initially I was hoping for a magical jQuery function that I'd perhaps overlooked, something along the lines of:

$("#parent-element").monitorDom(function(added_element){ ... });

...but there just isn't anything, which is probably a good thing because I suspect I've stumbled onto poor code design, and allowing for hooks and callbacks is a better way to go. I.e.: use the smaller, established and tested building blocks instead of trying to over-engineer something.

If you don't care about supporting Internet Explorer and it's quirks, you may definitely look at the deprecated mutation events, or their replacement the MutationObserver. Here is also a decently answered SO question with the use of mutators: Is there a JavaScript/jQuery DOM change listener?

In a nutshell, as of this post, there is no built-in jQuery function to monitor DOM changes, and in my case my problem can be resolved with better code design. Thank you all for all the answers, and let's keep pushing the limits!

Upvotes: 1

kasper Taeymans
kasper Taeymans

Reputation: 7026

Hi I made a jsfiddle dealing with your issue. The click on the button simulates your external libary adding a element. Unrelated to the button click I'm listening on DOMNodeInserted. If there is something inserted in the dom a class is added. You could easily modify the script to only add a class to certain elements.

http://jsfiddle.net/kasperfish/AAd8f/

$(function() {
    $('#btn').click(function(){
        $('body').append('<div style="width:30px;height:30px;border:1px solid black"></div>');
    });


    $(document).on('DOMNodeInserted', function(e) {

        $(e.target).addClass('blue');
    });


});

Upvotes: 5

Ivan Demchenko
Ivan Demchenko

Reputation: 457

If I were you, I would use events. jQuery makes it easy. Here are the first three links from Google: http://www.sitepoint.com/jquery-custom-events/, https://stackoverflow.com/a/14840483/993216, http://api.jquery.com/trigger/.

In one module you load the data from server, perhaps process it and trigger the event. In another module you can listen to that event and do whatever you need. In my opinion this is the best approach. This is very agile way to build and app because you can add another modules.

Upvotes: 0

MaVRoSCy
MaVRoSCy

Reputation: 17839

You can do something like:

$("body").bind("DOMNodeInserted", function() {
   $(this).find('.newly_created_element').addClass('my_own_class');
});

See more on DOMNodeInserted here

Upvotes: 15

hvgeertruy
hvgeertruy

Reputation: 190

Surely there is a wrapper class or id that library uses that you can use too. Just add css styling to that wrapper. I never found a library where I couldn't hook onto it's wrapper class/id definition.

Failing that, you need act on changes made by that script. Possibly by adding a listener to a specific user interaction or, like you mentioned, a DOM update. Maybe you can add a listener or callback on the external script itself.

I could give a more accurate answer on that if I knew more about the specific external script.

Regarding your snippet: you can listen for DOM updates like this $(".newly_created_element").bind(DOMSubtreeModified, function() { this.addClass('class'); });

Upvotes: 2

Related Questions