1

Goal:

Append a DOM element with functionality. (One global listener is not desire here.)

Problem:

I don't know how to reference the new element in this context. The problem area is the .on event listener and the references to $(this) contained inside. Also, the ability for the function get_value() to call itself again from within.

Relevant Code:

var dom_element = (function() {
    // [...]
    var create = function create( data ) {
        // [...]
        return $('<div />', { 'class': 'element', id: data.i_id })
            // [...]
            .on('load', function get_value() {
                // [...]
                $(this).find('.value').text(s_value);
                // [...]
                setTimeout('get_value()', 5000);
            }());
    },
    // [...]
    return {
        create: create
    };
}());
Donnie
  • 6,229
  • 8
  • 35
  • 53
  • 5
    Don't pass strings to `setTimeout`, it `eval`s them. Pass functions: `setTimeout(get_value, 5000);`. – gen_Eric Apr 16 '12 at 18:57

3 Answers3

3

The load event won't work on a <div> element.

If you want to perform some action when the content of the div is updated, you should do so in the code that updates the content.

var dom_element = (function() {
    // [...]
    var create = function create( data ) {
        // [...]
        var div =  $('<div />', { 'class': 'element', id: data.i_id })
            // [...]
        (function get_value(div) {
            // [...]
            $(div).find('.value').text(s_value);
            // [...]
            setTimeout(function() {
                get_value(div);
            }, 5000);
        })(div);

        return div;
    },
    // [...]
    return {
        create: create
    };
}());

I updated the code to do what I assume you're looking for.

  • He can use `mutation events` as well. (Yes I know they're deprecated...) – gdoron Apr 16 '12 at 19:01
  • @gdoron: What's a "mutation event"? – gen_Eric Apr 16 '12 at 19:08
  • @gdoron: True. I think I was misunderstanding the intent of the code at first. Seems like it's just an update on an interval. –  Apr 16 '12 at 19:09
  • 2
    @Rocket. [mutation events](http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-eventgroupings-mutationevents). [Example why it's needed](http://stackoverflow.com/a/9628472/601179). – gdoron Apr 16 '12 at 19:13
1

As another had said, on.('load'...) doesn't apply here. You're creating these elements dynamically (presumably after the DOM is all ready) so you should be able to start the timeouts right away. Here's my take:

var make_new = function(data){
    var $div = $('<div>', {'class': 'element', 'id':'element_'+data});
    var func = function(){
        // closure has formed around data, $div, and func
        // so references to them here reference the local versions
        // (the versions outside this immediate function block. i.e,
        // inside this call of make_new)
        data++;
        $div.text($div.attr('id') + ":" + data);
        setTimeout(func, 1000);
    };
    func();  //start process rolling
    return $div;
};

Basically, you should take advantage of js closures to capture the references that you need. func() is called before returning the div element, but there's nothing stopping you from returning both the element and func, and calling func() later.

Check out the jsfiddle of this here: http://jsfiddle.net/gRfyH/

shu zOMG chen
  • 436
  • 3
  • 8
0

The scope of a event handler is always the element, so using this you're doing everything right to reference the created <div> from get_value.

Yet, when you call get_value from the timeout, it will be executed in the global context. So you need to bind() the function to the element before passing it in setTimeout:

setTimeout(get_value.bind(this), 5000);

Or you do it manually:

var el = this;
setTimeout(function() {
    get_value.call(el);
}, 5000);
Bergi
  • 630,263
  • 148
  • 957
  • 1,375