Adrian Florescu
Adrian Florescu

Reputation: 4492

jQuery selector - select new elements too after append/load within variable

I have:

$elements = $('.elements');
$element = $('.element');


function appendText(element){
    element.append('<em> appended text</em>');
}

appendText($element);

$('button').on('click', function(){
        $elements.append('<span class="element">Span Element Appended after load</span>');
        appendText($element);
});

The appendText function, after button click, appends only to the initial element and that is due to JS cache I presume.

I know that I can do appendText($('element')); and the problem will be solved, but I don't want to change all my code now.

Is there any way to make jQuery consider this $element variable as not a cached element and look into the full DOM each time I call that variable?

Please find the jsfiddle if you wish to play or understand better: http://jsfiddle.net/adyz/733Xd/

Upvotes: 2

Views: 442

Answers (5)

eithed
eithed

Reputation: 4320

I don't think what you're asking is easily possible - when you call $element = $('.element'); you define a variable which equals to set of objects (well, one object). When calling appendText($element); you're operating on that object. It's not a cache - it's just how JS (and other programming languages) works.

The only solution I can see is to have a function that will update the variable, every time jquery calls one of its DOM manipulation methods, along the lines of this:

<div class='a'></div>
$(document).ready(function()
{
    var element = $('.a');

    $.fn.appendUpdate = function(elem)
    {
        // ugly because this is an object
        // also - not really taking account of multiple objects that are added here
        // just making an example

        if ($(elem).is(this.selector))
        {
            this[this.length] = $(this).append(elem).get(0);
            this.length++;
        }

        return this;
    }

    element.appendUpdate("<div class='a'></div>");
    console.log(element);
});

Then you can use sub() to roll out your own version of append = the above. This way your variables would be up to date, and you wouldn't really need to change your code. I also need to say that I shudder about the thing I've written (please, please, don't use it).

Fiddle

Upvotes: 0

midhun
midhun

Reputation: 157

Possible Solution will be

$(function(){

$elements = $('.elements');
$element = $('.element');

function appendText(element){
    element.append('<em> appended text</em>');
}

appendText($element);

$('button').on('click', function(){
        $elements.append('<span class="element">Span Element Appended after load</span>');
        appendText($elements.find('span').last());
});



})

Upvotes: 0

Kishorevarma
Kishorevarma

Reputation: 956

I think below one will solve your problem

   appendText($element); //here you always referring to the node which was there initial.

   http://jsfiddle.net/s9udJ/

Upvotes: 0

fmsf
fmsf

Reputation: 37137

That is an expensive thing to do. I would advise against it for performance reasons.

I did this pluggin in the beggining of last year https://github.com/fmsf/jQuery-obj-update

It doesn't trigger on every call, you have to request the update yourself:

$element.update();

The code is small enough to be pasted on the answer:

(function ( $ ) {
  $.fn.update = function(){
    var newElements = $(this.selector),i;    
    for(i=0;i<newElements.length;i++){
      this[i] = newElements[i];
    }
    for(;i<this.length;i++){
      this[i] = undefined;
    }
    this.length = newElements.length;
    return this;
  };
})(jQuery);

Upvotes: 1

Borza Adrian
Borza Adrian

Reputation: 530

If you add this:

$element = $('.element:last-child')

before

appendText($element);

I think will solve your problem jsFindle here: http://jsfiddle.net/733Xd/5/.

Best regards!

Upvotes: 2

Related Questions