jQuery / Selector / :empty - 내용이 없는 빈 요소를 선택하는 선택자

jQuery의 :empty는 자식 요소와 텍스트가 없는 요소를 선택합니다. $("#data td:empty")처럼 범위를 좁혀 빈 표 셀에 기본 내용을 넣을 수 있습니다. 화면에서 비어 보이더라도 공백이나 자식 태그가 있으면 선택되지 않으며, 주석만 있는 요소는 선택됩니다.

어떤 요소를 빈 요소로 판단할까요?

jQuery :empty 문서에서 말하는 내용에는 텍스트 노드도 포함됩니다. 즉, 태그 사이의 들여쓰기·줄바꿈도 공백 텍스트가 될 수 있습니다. 아래는 이 글의 예제를 jQuery 4.0.0과 3.7.1로 실행하여 확인한 구분입니다.

요소 안의 내용 :empty 선택 이유
아무것도 없음 선택 자식 요소와 텍스트가 없음
공백·줄바꿈·  제외 공백도 텍스트 노드임
주석만 있음 선택 주석은 이 판정의 내용에 포함되지 않음
빈 span 또는 br 태그 제외 자식 요소가 존재함

주석을 제외하는 구분은 CSS Selectors Level 3의 :empty 정의에도 나옵니다. 요소에 title이나 class 속성이 있다고 비어 있지 않은 것은 아닙니다. 반대로 자식이 display:none으로 숨겨져 있어도 구조에서 사라진 것은 아니므로 화면의 모양만으로 판단하지 않습니다.

빈 표 셀에 N/A를 채우는 전체 예제

다음 전체 코드를 UTF-8의 empty-demo.html로 저장하고 브라우저에서 엽니다. 별도 설치는 없지만 CDN(Content Delivery Network, 콘텐츠 전송 네트워크)에서 jQuery를 불러오므로 인터넷 연결이 필요합니다. 이 예제는 공식 배포 파일인 jQuery 4.0.0을 고정하여 사용합니다.

blank는 정말 빈 셀, spaces는 공백 세 칸, comment는 주석만 있는 셀입니다. nested의 span과 break의 br은 화면에 글자가 없어도 자식 요소입니다. 결과 안내와 버튼은 선택 범위인 표 밖에 배치합니다.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Empty table cells</title>
  <style>
    body { font: 16px/1.6 sans-serif; margin: 24px; }
    table { border-collapse: collapse; width: 100%; max-width: 600px; }
    td { border: 1px solid #aaa; padding: 16px; min-width: 80px; }
    .is-empty { background: #fff0b3; }
    button { margin: 16px 8px 0 0; padding: 8px; }
  </style>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
</head>
<body>
  <h1>Empty table cells</h1>
  <table id="data">
    <tr><td id="blank"></td><td id="spaces">   </td></tr>
    <tr><td id="comment"><!-- note --></td><td id="text">Hello</td></tr>
    <tr><td id="nested"><span></span></td><td id="break"><br></td></tr>
  </table>
  <button type="button" id="fill">Fill empty cells</button>
  <button type="button" id="reset">Reset</button>
  <p id="result" aria-live="polite"></p>
  <script>
    $(function () {
      function render() {
        const $empty = $("#data td:empty");
        $("#data td").removeClass("is-empty");
        $empty.addClass("is-empty");
        const ids = $empty.map((_, cell) => cell.id).get().join(", ");
        $("#result").text(`${ids || "none"} | ${$empty.length}`);
      }
      $("#fill").on("click", function () {
        $("#data td:empty").text("N/A");
        render();
      });
      $("#reset").on("click", function () {
        $("#blank, #comment").empty();
        render();
      });
      render();
    });
  </script>
</body>
</html>

처음 열었을 때 결과 문단은 다음과 같으며, blank와 comment 셀 두 개가 노란색으로 표시됩니다.

blank, comment | 2

결과를 확인하고 원래 상태로 되돌리기

  1. Fill empty cells 버튼을 누릅니다. 선택된 두 셀에 N/A가 들어가고, 새로 검사한 결과는 none | 0이 됩니다.
  2. spaces·nested·break 셀을 확인합니다. 공백 또는 자식 태그가 있으므로 N/A로 바뀌지 않습니다.
  3. Reset을 누릅니다. blank와 comment의 내용을 비우고 두 셀이 다시 선택됩니다. 이 초기화는 예제의 두 셀만 대상으로 하며, 처음의 주석 자체를 복원하지는 않습니다.

.text("N/A")를 사용해 표시할 문자열을 넣습니다. 셀을 채우고도 노란 표시가 남는 문제를 피하려고 render는 전체 셀의 표시 클래스를 먼저 지운 뒤 현재 빈 셀에만 다시 붙입니다. 기능 실행과 화면 상태 갱신을 함께 확인합니다.

범위를 좁히고 변경 뒤 다시 선택하기

전체 문서의 모든 빈 요소를 고르는 $(":empty")보다 목적이 분명한 $("#data td:empty")를 사용합니다. 표 밖의 빈 요소나 span·br까지 의도치 않게 선택하는 일을 줄일 수 있습니다. 예제 파일을 처음 열거나 Reset을 누른 뒤 개발자 도구의 콘솔에서 다음 부분 코드를 실행하면 현재 선택 개수와 ID를 확인할 수 있습니다.

const $empty = $("#data td:empty");
console.log($empty.length);
console.log($empty.map((_, cell) => cell.id).get().join(", "));
2
blank, comment

jQuery 선택 결과는 문서가 바뀌면 자동 갱신되는 실시간 목록이 아닙니다. 위의 $empty를 저장한 뒤 셀을 채워도 저장된 객체의 length는 2입니다. 현재 빈 셀 수를 확인하려면 선택자를 다시 실행해야 하므로 예제의 render에서도 매번 새로 선택합니다.

.empty()·:parent·입력값 검사와 구분하기

:empty는 선택 조건이고 .empty() 메서드는 선택한 요소의 자식 내용과 텍스트를 제거하는 동작입니다. 이 메서드는 선택한 표 셀 자체는 남기므로 Reset 버튼에 사용할 수 있습니다. 반대 조건을 고르는 :parent 선택자는 자식 요소 또는 텍스트가 있는 요소를 고르며, 부모로 이동하는 .parent() 메서드와도 다릅니다.

input은 자식 내용을 담지 않는 요소여서 value에 JB가 있어도 :empty에 일치할 수 있습니다. 사용자가 입력했는지 판단할 때는 .val()로 현재 입력값을 읽고 빈 문자열인지 검사합니다. 공백만 입력한 값도 빈 값으로 취급할지는 별도 정책입니다. ‘빈 요소’와 ‘빈 입력값’을 같은 조건으로 처리하지 않습니다.

예제에서 아무 반응이 없으면 개발자 도구의 Network에서 jQuery 파일이 정상적으로 불러와졌는지, Console에 $ is not defined 같은 오류가 있는지 확인합니다. HTML과 선택자의 ID가 일치하는지, 빈 셀의 태그 사이에 편집 과정에서 공백이 추가되지 않았는지도 함께 확인합니다.