jQuery / Selector / :selected - select에서 선택된 option를 선택하는 선택자
jQuery의 :selected는 select 안에서 현재 선택된 option 요소를 고르는 선택자입니다. $("#fruit option:selected")로 선택된 option을 얻고, 값만 필요하면 $("#fruit").val()을 사용합니다. HTML에 적힌 selected 속성과 사용자가 바꾼 현재 선택 상태는 다를 수 있습니다.
option 요소·값·표시명을 구분하기
:selected 공식 문서의 대상은 option이며 체크박스와 라디오에는 사용하지 않습니다. 먼저 대상 select를 id나 폼 범위로 한정합니다. 페이지 전체의 option:selected를 읽으면 다른 select의 선택까지 섞일 수 있습니다.
선택된 option의 .text()는 표시명이고 .val()은 value입니다. 여러 option을 선택한 집합에 .val()을 쓰면 첫 요소의 값만 읽으며, .text()는 모든 텍스트를 이어 붙입니다. 다중 선택의 값 전체가 필요하면 select 자체의 .val()을, 선택 요소별 정보가 필요하면 map이나 each를 사용합니다.
이 예제에서는 과일 한 개와 여러 주제를 구분합니다. 표시명 JavaScript와 제출 값 js처럼 둘을 다르게 두었습니다. disabled와 비활성 optgroup 안의 선택 항목도 넣어, 선택된 상태와 제출 가능한 상태가 같은 개념이 아님을 비교합니다.
단일·다중 선택을 확인하는 전체 예제
UTF-8의 selected-demo.html로 저장하고 브라우저로 엽니다. 인터넷에서 jQuery 전체 파일 4.0.0을 읽으며 서버나 빌드는 필요 없습니다. Windows Edge에서 4.0.0·3.7.1으로 초기 상태, 키보드 선택, 비활성 옵션, 빈 선택과 Reset을 확인했습니다.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Read selected options and submitted values</title>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<style>
body { font: 16px/1.6 sans-serif; max-width: 740px; margin: 20px; }
label { display: block; margin-top: 12px; }
select, button { font: inherit; max-width: 100%; margin: 6px 0; }
#topics { display: block; min-width: 230px; }
pre { white-space: pre-wrap; overflow-wrap: anywhere; }
</style>
</head>
<body>
<form id="chooser">
<label for="fruit">Fruit (single)</label>
<select id="fruit" name="fruit"><option value="apple">Apple</option><option value="banana">Banana</option></select>
<label for="topics">Topics (multiple)</label>
<select id="topics" name="topics" multiple size="6">
<option value="js" selected>JavaScript</option>
<option value="css">CSS</option>
<option value="html" selected disabled>HTML (disabled)</option>
<optgroup label="Unavailable group" disabled><option value="legacy" selected>Legacy</option></optgroup>
</select>
<button type="button" id="set">Set Banana and CSS</button>
<button type="button" id="clear">Clear topics</button>
<button type="button" id="restore">Reset</button>
</form>
<pre id="result" aria-live="polite"></pre>
<script>
jQuery(function ($) {
const $fruit = $("#fruit"), $topics = $("#topics"), form = document.querySelector("#chooser");
let changes = 0;
function values($options) { return $options.map(function () { return this.value; }).get(); }
function render() {
const $selected = $topics.find("option").filter(":selected");
const data = new URLSearchParams(new FormData(form));
$("#result").text("single=" + $fruit.val() + "\nsingleText=" + $fruit.find("option:selected").text() +
"\nselectedOptions=" + JSON.stringify(values($selected)) + "\nvalues=" + JSON.stringify($topics.val()) +
"\nselectedAttribute=" + JSON.stringify(values($topics.find("option[selected]"))) +
"\nform=" + data.toString() + "\nchanges=" + changes);
}
$fruit.add($topics).on("change", function () { changes++; render(); });
$("#set").on("click", function () {
$fruit.val("banana").trigger("change"); $topics.val(["css"]).trigger("change");
});
$("#clear").on("click", function () { $topics.val([]).trigger("change"); });
$("#restore").on("click", function () { form.reset(); changes = 0; render(); });
render();
});
</script>
</body>
</html>
초기 출력입니다. Fruit에는 selected 속성이 없지만 단일 select의 첫 항목 Apple이 현재 선택됩니다. Topics의 세 항목은 selected 상태지만 제출 가능한 값은 js 하나입니다.
single=apple
singleText=Apple
selectedOptions=["js","html","legacy"]
values=["js"]
selectedAttribute=["js","html","legacy"]
form=fruit=apple&topics=js
changes=0
- Fruit에서 Banana를 선택합니다. single=banana와 singleText=Banana가 함께 바뀝니다. 키보드 방향키로 바꿔도 change에서 갱신됩니다.
- Set Banana and CSS를 누릅니다. selectedOptions와 values는 모두 ["css"]가 되지만 selectedAttribute는 여전히 ["js","html","legacy"]입니다.
- Clear topics를 누르면 selectedOptions와 values는 []가 됩니다. form에는 fruit만 남고 topics 항목은 없습니다.
- Reset으로 초기 상태를 복원합니다. HTML과 Legacy의 비활성 선택 상태도 원래대로 돌아옵니다.
- 다중 선택을 직접 조작할 때는 운영체제·브라우저에 맞는 여러 항목 선택 키를 사용합니다. 버튼은 기기별 조작 차이 없이 비교 조건을 만들기 위한 것입니다.
selectedOptions는 선택된 DOM 요소들의 value, values는 select에 대한 .val(), selectedAttribute는 HTML 속성이 남은 항목입니다. form은 FormData로 만든 실제 폼 데이터의 URL 쿼리 표현이며 서버로 보내지 않습니다. changes는 change 처리 횟수로, 버튼의 두 select 설정은 각각 이벤트를 발생시키므로 2회입니다.
현재 상태와 기본 selected 속성
DOM의 option.selected와 :selected는 현재 선택을 나타냅니다. 반면 [selected]는 속성 존재를 고르고 defaultSelected는 기본 선택과 연결됩니다. 사용자가 선택을 바꿔도 기본 속성이 같은 방식으로 함께 바뀌지는 않으므로, 현재 선택 검사에 [selected]를 사용하지 않습니다.
.val(["css"])는 현재 선택을 바꾸고 .val([])는 다중 선택을 비웁니다. .val() 문서처럼 setter는 change를 자동 발생시키지 않아 예제는 .trigger("change")로 화면도 갱신합니다. 값만 바꾸고 이벤트나 render를 호출하지 않으면 화면의 보고 내용이 이전 상태로 보일 수 있습니다.
jQuery 3 이상에서 아무것도 고르지 않은 다중 select의 .val()은 []입니다. 선택 option을 찾은 집합 자체가 비어 있을 때 그 집합의 .val()은 undefined이며, 단일 select에 존재하지 않는 값을 설정해 선택이 없어지면 select의 .val()은 null입니다. 빈 상태를 모두 빈 문자열이라고 가정하지 않습니다.
Reset은 form.reset() 후 render를 직접 호출해 기본 선택과 출력을 맞춥니다. 현재 selected 속성을 새로 편집해 기본값 자체를 바꿨다면 복원 결과도 달라질 수 있습니다. 이 실습은 속성은 유지하고 현재 값만 바꾸므로 초기 비교 상태로 돌아옵니다.
비활성 항목·:checked·실제 적용
선택은 되어 있어도 disabled인 option과 비활성 optgroup 안의 option은 select의 .val()과 FormData에서 제외됩니다. 따라서 :selected의 개수가 곧 실제 제출 값의 개수라고 판단하지 않습니다. 예제 초기 selectedOptions는 세 개인데 values는 하나인 이유입니다. name이 없거나 select 자체가 비활성인 경우도 제출 데이터 구성과 함께 확인해야 합니다.
:checked는 체크박스·라디오뿐 아니라 선택된 option에도 맞습니다. option:checked로 제한하면 이 예제에서 같은 선택 option을 얻습니다. 다만 :checked만 페이지 전체에서 읽으면 체크박스·라디오까지 섞이므로 목적에 맞는 범위를 사용합니다.
:selected는 jQuery 확장이어서 document.querySelectorAll("option:selected") 같은 표준 DOM 조회에 그대로 넣을 수 없습니다. 예제는 먼저 CSS로 option 범위를 고른 다음 .filter(":selected")를 적용합니다. 네이티브 코드에서는 select.selectedOptions나 범위를 제한한 option:checked를 검토할 수 있습니다.
선택 결과를 색상·필터 등에 적용한다면 이벤트만 기다리지 말고 페이지 준비 직후에도 한 번 반영해 초기 화면을 맞춥니다. 프로그램으로 선택을 바꿨을 때의 갱신 경로도 정하고, 표시 문구를 .html()에 이어 붙이기보다 .text()로 출력합니다. 서버에서는 브라우저가 보낸 value가 허용 목록과 업무 조건에 맞는지 다시 검사합니다.




