jQuery / Property / .length - Count Selected Elements

jQuery's .length is a numeric property giving the number of elements in a jQuery object. Read it without parentheses, as in $("#tasks > li").length; no matches means zero. To count the current document after inserting or removing elements, run the selection again.

Count elements and test existence

The .length documentation concerns a selected collection. It does not count text inside an element or that element's children. Hidden elements count if they match the selector. Narrow the condition to count only the relevant subset.

Expression What it checks
$("#tasks > li").length Direct li children of the list
$("#tasks > li.done").length Matching li elements with the done class
$("#tasks > li").length > 0 At least one matching element exists
$("#missing-item").length === 0 No element with that ID exists

if ($("#missing-item")) is not an existence test. jQuery still creates an object when nothing matches, and the object itself is truthy. Check its .length against zero. This property is not a function: calling .length() throws TypeError.

Complete example with insertion and removal

Save all the code in UTF-8 as length-demo.html and open it in a browser. No installation is needed, but loading the official jQuery file from its Content Delivery Network (CDN) requires internet. The code uses 4.0.0. Counts, existence checks, insertion, removal and reset were executed with 3.7.1 and 4.0.0.

The initial list contains Alpha and Beta. CSS hides Beta, but it remains in the document and has the done class. current is the fresh selection's count, completed counts done within it, and saved is the count in the collection stored at startup.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Count selected list elements</title>
  <style>
    body { font: 16px/1.6 sans-serif; margin: 24px; }
    li { padding: 8px; border-bottom: 1px solid #ddd; }
    .is-hidden { display: none; }
    button { padding: 8px; margin: 4px; }
    #result { white-space: pre-line; }
  </style>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
  <h1>Count selected list elements</h1>
  <p>One initial item is hidden but remains in the document.</p>
  <ul id="tasks">
    <li id="alpha">Alpha</li>
    <li id="beta" class="done is-hidden">Beta</li>
  </ul>
  <button type="button" id="add">Add item</button>
  <button type="button" id="remove">Remove last</button>
  <button type="button" id="reset">Reset</button>
  <p id="result" aria-live="polite"></p>
  <script>
    $(function () {
      const initialHtml = $("#tasks").html();
      const $saved = $("#tasks > li");
      let next = 3;
      function refresh() {
        const $current = $("#tasks > li");
        $("#result").text(
          `current=${$current.length}
` +
          `completed=${$current.filter(".done").length}
` +
          `saved=${$saved.length}
` +
          `present=${$current.length > 0 ? "yes" : "no"}`
        );
      }
      $("#add").on("click", function () {
        $("<li>").text("New " + next++).appendTo("#tasks");
        refresh();
      });
      $("#remove").on("click", function () {
        $("#tasks > li").last().remove();
        refresh();
      });
      $("#reset").on("click", function () {
        $("#tasks").html(initialHtml);
        next = 3;
        refresh();
      });
      refresh();
    });
  </script>
</body>
</html>

Only Alpha is visible, but .length counts both li elements. The initial output is:

current=2
completed=1
saved=2
present=yes
  1. Add item appends New 3, increasing current to 3. completed stays 1 and saved stays 2.
  2. Remove last removes the new item, returning current to 2. Press again to remove hidden Beta: current becomes 1 and completed becomes 0.
  3. Press again to remove Alpha: current becomes 0 and present becomes no. Further clicks keep zero because no element remains to remove.
  4. Reset restores the saved initial HTML, resets new-item numbering to 3 and recounts. The original two elements, hidden state and done class return.

This demonstration restores fixed initial HTML. Replacing all HTML on a real editable screen would also discard user changes. Define the reset scope according to which data must be preserved.

Element count versus text length

After Reset, run this fragment in the developer console. The example has no element with ID missing-item.

if ($("#missing-item").length === 0) {
  console.log("not found");
}
console.log($("#tasks > li").length);
console.log($("#tasks > li").first().text().length);
not found
2
5

2 counts selected li elements; 5 is the length of the first element's Alpha string. .text() returns a string, so the following .length belongs to that string. The same property name has different meaning depending on whether its receiver is a jQuery object or a string.

Refresh counts, check timing and update old code

saved stays 2 because the initial jQuery collection is retained. Removing the original elements from the document does not automatically change its length. Reset creates new elements without replacing saved, so use a fresh query like refresh for current existence and counts.

Selecting too early can return zero before the elements exist. The example's DOM-ready callback, $(function () { ... }), runs when the Document Object Model (DOM) is ready for manipulation. Asynchronously inserted elements may arrive later; count them after insertion completes.

The old .size() method was removed in jQuery 3.0. Replace it with .length in current code. For unexpected values, check jQuery loading in Network, Console errors and version, selector scope/classes/IDs, and when insertion finishes.