gatzkerob gatzkerob - 4 months ago 10
jQuery Question

Javascript object property doesn't return correct length

I dynamically clone an element using jQuery and ask an object to return its length, but it returns

1
every time. Please see fiddle:

https://jsfiddle.net/gatzkerob/x5xd2x7q/3/

<span class="count">0</span>
<br>
<button>click</button>
<br>
<span class="a">a</span>

var obj = {
elem : $('.a')
}

function cloneThisAndCount(){
$('.a').last().after($('.a').first().clone());
$('.count').text(obj.elem.length);
}

$('button').click(function(){
cloneThisAndCount();
});

Answer
var obj = {
  elem : $('.a')
}

will be computed once and cached into obj.elem in the begenning. which will be 1.

Note (thanx to nnnnn): When you have a reference to a jQuery object it is possible that other code could update that object to add more elements to it.

SOLUTION 1:

What you need is to do is, redo the selector every time before calculating length.

function cloneThisAndCount() {
  $('.a').last().after($('.a').first().clone());
  $('.count').text($('.a').length);
}

$('button').click(function() {
  cloneThisAndCount();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="count">0</span>
<br>
<button>click</button>
<br>
<span class="a">a</span>

SOLUTION 2:

Change obj to:

var obj = {
  elem : function(){ return $('.a')}
}

and then check length like: $('.count').text(obj.elem().length);

var obj = {
  elem: function() {
    return $('.a')
  }
}

function cloneThisAndCount() {
  $('.a').last().after($('.a').first().clone());
  $('.count').text(obj.elem().length);
}

$('button').click(function() {
  cloneThisAndCount();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="count">0</span>
<br>
<button>click</button>
<br>
<span class="a">a</span>