0

The problem is simple. I have a massive javascript application. And there are lot of times in the app where I use code which looks something like this -

$('#treat').html(new_data);
....
....
$('#cool').html(some_html_data);
....
....
$('#not_cool').html(ajax_data);

So what I want to do is, everytime this html() function is called I want to execute a set of functions.

function do_these_things_every_time_data_is_loaded_into_a_div()   
{      
     $('select').customSelect();
     $('input').changeStyle();
     etc.
}

How do I do this? Thank you.

Sai Krishna
  • 7,647
  • 6
  • 29
  • 40
  • 1
    Wouldn't it be cleaner to just explicitly call your function from your AJAX success handlers? You could also try using the global [`ajaxComplete`](http://api.jquery.com/ajaxComplete/) event to post-process the AJAX response, but I don't know if that gets called before or after specific AJAX response handlers. – millimoose Oct 21 '13 at 12:23
  • 1
    Wrap `html()` in you own function which also calls those methods. – Rory McCrossan Oct 21 '13 at 12:24

5 Answers5

2

You can use the custom event handlers for that:

$('#treat').html(new_data);

// Trigger the custom event after html change
$('#treat').trigger('custom');

// Custom event handler
$('#treat').on('custom', function( event) {
  // do_these_things_every_time_data_is_loaded_into_a_div
  alert('Html had changed!');
});

UPDATE

Based on answer over here and with some modifications you can do this:

// create a reference to the old `.html()` function
$.fn.htmlOriginal = $.fn.html;

// redefine the `.html()` function to accept a callback
$.fn.html = function (html, callback) {
    // run the old `.html()` function with the first parameter
    this.htmlOriginal(html);
    // run the callback (if it is defined)
    if (typeof callback == "function") {
        callback();
    }
}

$("#treat").html(new_data, function () {
    do_these_things_every_time_data_is_loaded_into_a_div();
});

$("#cool").html(new_data, function () {
    do_these_things_every_time_data_is_loaded_into_a_div();
});

Easily maintainable and less code as per your requirements.

Community
  • 1
  • 1
palaѕн
  • 72,112
  • 17
  • 116
  • 136
  • 1
    This is probably the best idea, it's clean and decoupled. – millimoose Oct 21 '13 at 12:28
  • @palash, does he need to make this custom call for every happening `.html()` function? Wouldn't it be pretty lengthy? – Manoz Oct 21 '13 at 12:31
  • Please note that I have a massive javascript application and I cannot go around changing the code like that. What if I have to roll back the changes? It will get very messy. Thank you. – Sai Krishna Oct 21 '13 at 12:36
  • @palash in such case.. don't you think calling the function itself `do_these_things_every_time_data_is_loaded_into_a_div()` before `html()` is better rather than creating a custom function ..OP already has that function defined... – bipen Oct 21 '13 at 12:36
  • @ZachWild: In the above mentioned scenario, you can go with this [code over here](http://stackoverflow.com/a/11826737/1823841) – palaѕн Oct 21 '13 at 12:40
1

You can overwrite the jQuery.fn.html() method, as described in Override jQuery functions

For example, use this:

var oHtml = jQuery.fn.html;
jQuery.fn.html = function(value) {
    if(typeof value !== "undefined")
    {
        jQuery('select').customSelect();
        jQuery('input').changeStyle();
    }
    // Now go back to jQuery's original html()
    return oHtml.apply(this, value);
};
Community
  • 1
  • 1
Sjerdo
  • 187
  • 1
  • 4
0

When html() is called it usually make the DOM object changes, so you can look for DOM change event handler, it is called whenever your HTML of main page change. I found

Is there a JavaScript/jQuery DOM change listener?

if this help your cause.

Community
  • 1
  • 1
Sumit Gupta
  • 2,152
  • 4
  • 29
  • 46
  • DOM changes are for all intents and purposes unusable. The old API is deprecated, and the new one is unsupported in IE. – millimoose Oct 21 '13 at 12:27
0

You can replace the html function with your own function and then call the function html:

$.fn.html = (function(oldHtml) {
        var _oldHtml = oldHtml;

        return function(param) {
            // your code
            alert(param);
            return _oldHtml.apply(this, [param]);
        };
    })($.fn.html);
edotassi
  • 476
  • 2
  • 6
  • 19
0

I have a little script for you. Insert that into your javascript:

//@Author Karl-André Gagnon
$.hook = function(){
    $.each(arguments, function(){
        var fn = this
        if(!$.fn['hooked'+fn]){
            $.fn['hooked'+fn] = $.fn[fn];
            $.fn[fn] = function(){
                var r = $.fn['hooked'+fn].apply(this, arguments);
                $(this).trigger(fn, arguments);
                return r
            }
        }
    })
}

This allow you to "hook" jQuery function and trigger an event when you call it.

Here how you use it, you first bind the function you want to trigger. In your case, it will be .html():

$.hook('html');

Then you add an event listener with .on. It there is no dynamicly added element, you can use direct binding, else, delegated evets work :

$(document).on('html', '#threat, #cool, #not_cool',function(){
    alert('B');
})

The function will launch everytime #threat, #cool or #not_cool are calling .html.

The $.hook plugin is not fully texted, some bug may be here but for your HTML, it work.

Example : http://jsfiddle.net/5svVQ/

Karl-André Gagnon
  • 33,662
  • 5
  • 50
  • 75