Hộp tổ hợp trong HTML

Ví dụ triển khai Mẫu Combobox sau đây minh họa tiện ích hộp tổ hợp chọn một lần có chức năng tương tự như phần tử _______ _ _ HTML. Không giống như các ví dụ về hộp tổ hợp có thể chỉnh sửa, hộp tổ hợp chỉ chọn này không được tạo bằng phần tử và nó không chấp nhận đầu vào của người dùng dạng tự do. Tuy nhiên, giống như phần tử HTML , users can type characters to select matching options. Similar examples include: Keyboard Support The example combobox on this page implements the following keyboard interface. Other variations and options for the keyboard interface are described in the Keyboard Interaction section of the combobox pattern. Closed Combobox Key Function Down Arrow Opens the listbox if it is not already displayed without moving focus or changing selection. DOM focus remains on the combobox. Alt + Down Arrow Opens the listbox without moving focus or changing selection. Up Arrow First opens the listbox if it is not already displayed and then moves visual focus to the first option. DOM focus remains on the combobox. Enter Opens the listbox without moving focus or changing selection. Space Opens the listbox without moving focus or changing selection. Home Opens the listbox and moves visual focus to the first option. End Opens the listbox and moves visual focus to the last option. Printable Characters First opens the listbox if it is not already displayed and then moves visual focus to the first option that matches the typed character. If multiple keys are typed in quick succession, visual focus moves to the first option that matches the full string. If the same character is typed in succession, visual focus cycles among the options starting with that character. Listbox Popup NOTE: When visual focus is in the listbox, DOM focus remains on the combobox and the value of aria-activedescendant on the combobox is set to a value that refers to the listbox option that is visually indicated as focused. Where the following descriptions of keyboard commands mention focus, they are referring to the visual focus indicator. For more information about this focus management technique, see Managing Focus in Composites Using aria-activedescendant. Key Function Enter Sets the value to the content of the focused option in the listbox. Closes the listbox. Sets visual focus on the combobox. Space Sets the value to the content of the focused option in the listbox. Closes the listbox. Sets visual focus on the combobox. Tab Sets the value to the content of the focused option in the listbox. Closes the listbox. Performs the default action, moving focus to the next focusable element. Note: the native đóng hộp danh sách nhưng không di chuyển tiêu điểm trên tab. Mẫu này khớp với hành vi của các hộp tổ hợp khác chứ không phải phần tử gốc trong trường hợp này. Bỏ trốn

  • Đóng hộp danh sách
  • Đặt tiêu điểm trực quan trên hộp tổ hợp
mũi tên xuống
  • Di chuyển tiêu điểm trực quan sang tùy chọn tiếp theo
  • Nếu tiêu điểm hình ảnh ở tùy chọn cuối cùng, tiêu điểm hình ảnh không di chuyển
Mũi tên lên
  • Di chuyển tiêu điểm trực quan đến tùy chọn trước đó
  • Nếu tiêu điểm hình ảnh ở tùy chọn đầu tiên, tiêu điểm hình ảnh không di chuyển
Alt + Mũi tên lên
  • Đặt giá trị cho nội dung của tùy chọn tập trung trong hộp danh sách
  • Đóng hộp danh sách
  • Đặt tiêu điểm trực quan trên hộp tổ hợp
Trang chủ Di chuyển tiêu điểm trực quan đến tùy chọn đầu tiên. Kết thúc Di chuyển tiêu điểm trực quan đến tùy chọn cuối cùng. PageUp Nhảy tập trung trực quan lên 10 tùy chọn (hoặc tùy chọn đầu tiên). PageDown Nhảy tiêu điểm trực quan xuống 10 tùy chọn (hoặc đến tùy chọn cuối cùng). Nhân vật có thể in
  • Đầu tiên mở hộp danh sách nếu nó chưa được hiển thị và sau đó di chuyển tiêu điểm trực quan đến tùy chọn đầu tiên khớp với ký tự đã nhập
  • Nếu nhiều phím được nhập liên tiếp, tiêu điểm trực quan sẽ di chuyển đến tùy chọn đầu tiên khớp với toàn bộ chuỗi
  • Nếu cùng một ký tự được nhập liên tiếp, tiêu điểm hình ảnh sẽ xoay vòng giữa các tùy chọn bắt đầu bằng ký tự đó

Ví dụ trên cho thấy cách sử dụng

Mỗi phần tử

<label>Please choose one or more pets:
  <select name="pets" multiple size="4">
    <optgroup label="4-legged pets">
      <option value="dog">Dogoption>
      <option value="cat">Catoption>
      <option value="hamster" disabled>Hamsteroption>
    optgroup>
    <optgroup label="Flying pets">
      <option value="parrot">Parrotoption>
      <option value="macaw">Macawoption>
      <option value="albatross">Albatrossoption>
    optgroup>
  select>
label>
0 phải có một thuộc tính chứa giá trị dữ liệu để gửi tới máy chủ khi tùy chọn đó được chọn. Nếu không bao gồm thuộc tính
<label>Please choose one or more pets:
  <select name="pets" multiple size="4">
    <optgroup label="4-legged pets">
      <option value="dog">Dogoption>
      <option value="cat">Catoption>
      <option value="hamster" disabled>Hamsteroption>
    optgroup>
    <optgroup label="Flying pets">
      <option value="parrot">Parrotoption>
      <option value="macaw">Macawoption>
      <option value="albatross">Albatrossoption>
    optgroup>
  select>
label>
3, giá trị sẽ mặc định là văn bản chứa bên trong phần tử. Bạn có thể bao gồm một thuộc tính trên một phần tử
<label>Please choose one or more pets:
  <select name="pets" multiple size="4">
    <optgroup label="4-legged pets">
      <option value="dog">Dogoption>
      <option value="cat">Catoption>
      <option value="hamster" disabled>Hamsteroption>
    optgroup>
    <optgroup label="Flying pets">
      <option value="parrot">Parrotoption>
      <option value="macaw">Macawoption>
      <option value="albatross">Albatrossoption>
    optgroup>
  select>
label>
0 để làm cho nó được chọn theo mặc định khi tải trang lần đầu tiên

Phần tử với (chủ sở hữu biểu mẫu của nó). Giá trị của thuộc tính này phải là của một

body {
  font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif;
}

.select:focus {
  border-color: blue;
}

html body form fieldset#custom div.select[data-multiple] div.header {
  display: none;
}

html body form fieldset#custom div.select div.header {
  content: "↓";
  display: flex;
  flex: 1;
  align-items: center;
  padding: 0;
  position: relative;
  width: auto;
  box-sizing: border-box;
  border-width: 1px;
  border-style: inherit;
  border-color: inherit;
  border-radius: inherit;
}

html body form fieldset#custom div.select div.header::after {
  content: "↓";
  align-self: stretch;
  display: flex;
  align-content: center;
  justify-content: center;
  justify-items: center;
  align-items: center;
  padding: 0.5em;
}

html body form fieldset#custom div.select div.header:hover::after {
  background-color: blue;
}

.select .header select {
  appearance: none;
  font-family: inherit;
  font-size: inherit;
  padding: 0;
  border-width: 0;
  width: 100%;
  flex: 1;
  display: none;
}

.select .header select optgroup {
  display: none;
}

.select select div.option {
  display: none;
}

html body form fieldset#custom div.select {
  user-select: none;
  box-sizing: border-box;
  position: relative;
  border-radius: 4px;
  border-style: solid;
  border-width: 0;
  border-color: gray;
  width: auto;
  display: inline-block;
}

html body form fieldset#custom div.select:focus,
html body form fieldset#custom div.select:hover {
  border-color: blue;
}

html body form fieldset#custom div.select[data-open] {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

html body form fieldset#custom div.select[data-open] datalist {
  display: initial;
}

html body form fieldset#custom div.select datalist {
  appearance: none;
  position: absolute;
  border-style: solid;
  border-width: 1px;
  border-color: gray;
  left: 0;
  display: none;
  width: 100%;
  box-sizing: border-box;
  z-index: 2;
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
}

html body form fieldset#custom div.select datalist div.option {
  background-color: white;
  margin-bottom: 1px;
  cursor: pointer;
  padding: 0.5em;
  border-width: 0;
}

html body form fieldset#custom div.select datalist div.option:hover,
html body form fieldset#custom div.select datalist div.option:focus,
html body form fieldset#custom div.select datalist div.option:checked {
  background-color: blue;
  color: white;
}

html
  body
  form
  fieldset#custom
  div.select
  div.optgroup
  div.option[data-disabled] {
  color: gray;
}

html
  body
  form
  fieldset#custom
  div.select
  div.optgroup
  div.option[data-checked] {
  background-color: blue;
  color: white;
}

html body form fieldset#custom div.select div.optgroup div.label {
  font-weight: bold;
}

html body form fieldset#custom div.select div.optgroup div.option div.label {
  font-weight: normal;
  padding: 0.25em;
}

html body form fieldset#custom div.select div.header span {
  flex: 1;
  padding: 0.5em;
}
2 trong cùng một tài liệu. (Nếu thuộc tính này không được đặt, thì phần tử với các
body {
  font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif;
}

.select:focus {
  border-color: blue;
}

html body form fieldset#custom div.select[data-multiple] div.header {
  display: none;
}

html body form fieldset#custom div.select div.header {
  content: "↓";
  display: flex;
  flex: 1;
  align-items: center;
  padding: 0;
  position: relative;
  width: auto;
  box-sizing: border-box;
  border-width: 1px;
  border-style: inherit;
  border-color: inherit;
  border-radius: inherit;
}

html body form fieldset#custom div.select div.header::after {
  content: "↓";
  align-self: stretch;
  display: flex;
  align-content: center;
  justify-content: center;
  justify-items: center;
  align-items: center;
  padding: 0.5em;
}

html body form fieldset#custom div.select div.header:hover::after {
  background-color: blue;
}

.select .header select {
  appearance: none;
  font-family: inherit;
  font-size: inherit;
  padding: 0;
  border-width: 0;
  width: 100%;
  flex: 1;
  display: none;
}

.select .header select optgroup {
  display: none;
}

.select select div.option {
  display: none;
}

html body form fieldset#custom div.select {
  user-select: none;
  box-sizing: border-box;
  position: relative;
  border-radius: 4px;
  border-style: solid;
  border-width: 0;
  border-color: gray;
  width: auto;
  display: inline-block;
}

html body form fieldset#custom div.select:focus,
html body form fieldset#custom div.select:hover {
  border-color: blue;
}

html body form fieldset#custom div.select[data-open] {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

html body form fieldset#custom div.select[data-open] datalist {
  display: initial;
}

html body form fieldset#custom div.select datalist {
  appearance: none;
  position: absolute;
  border-style: solid;
  border-width: 1px;
  border-color: gray;
  left: 0;
  display: none;
  width: 100%;
  box-sizing: border-box;
  z-index: 2;
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
}

html body form fieldset#custom div.select datalist div.option {
  background-color: white;
  margin-bottom: 1px;
  cursor: pointer;
  padding: 0.5em;
  border-width: 0;
}

html body form fieldset#custom div.select datalist div.option:hover,
html body form fieldset#custom div.select datalist div.option:focus,
html body form fieldset#custom div.select datalist div.option:checked {
  background-color: blue;
  color: white;
}

html
  body
  form
  fieldset#custom
  div.select
  div.optgroup
  div.option[data-disabled] {
  color: gray;
}

html
  body
  form
  fieldset#custom
  div.select
  div.optgroup
  div.option[data-checked] {
  background-color: blue;
  color: white;
}

html body form fieldset#custom div.select div.optgroup div.label {
  font-weight: bold;
}

html body form fieldset#custom div.select div.optgroup div.option div.label {
  font-weight: normal;
  padding: 0.25em;
}

html body form fieldset#custom div.select div.header span {
  flex: 1;
  padding: 0.5em;
}
2 ở bất kỳ đâu trong tài liệu, không chỉ bên trong một
body {
  font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif;
}

.select:focus {
  border-color: blue;
}

html body form fieldset#custom div.select[data-multiple] div.header {
  display: none;
}

html body form fieldset#custom div.select div.header {
  content: "↓";
  display: flex;
  flex: 1;
  align-items: center;
  padding: 0;
  position: relative;
  width: auto;
  box-sizing: border-box;
  border-width: 1px;
  border-style: inherit;
  border-color: inherit;
  border-radius: inherit;
}

html body form fieldset#custom div.select div.header::after {
  content: "↓";
  align-self: stretch;
  display: flex;
  align-content: center;
  justify-content: center;
  justify-items: center;
  align-items: center;
  padding: 0.5em;
}

html body form fieldset#custom div.select div.header:hover::after {
  background-color: blue;
}

.select .header select {
  appearance: none;
  font-family: inherit;
  font-size: inherit;
  padding: 0;
  border-width: 0;
  width: 100%;
  flex: 1;
  display: none;
}

.select .header select optgroup {
  display: none;
}

.select select div.option {
  display: none;
}

html body form fieldset#custom div.select {
  user-select: none;
  box-sizing: border-box;
  position: relative;
  border-radius: 4px;
  border-style: solid;
  border-width: 0;
  border-color: gray;
  width: auto;
  display: inline-block;
}

html body form fieldset#custom div.select:focus,
html body form fieldset#custom div.select:hover {
  border-color: blue;
}

html body form fieldset#custom div.select[data-open] {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

html body form fieldset#custom div.select[data-open] datalist {
  display: initial;
}

html body form fieldset#custom div.select datalist {
  appearance: none;
  position: absolute;
  border-style: solid;
  border-width: 1px;
  border-color: gray;
  left: 0;
  display: none;
  width: 100%;
  box-sizing: border-box;
  z-index: 2;
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
}

html body form fieldset#custom div.select datalist div.option {
  background-color: white;
  margin-bottom: 1px;
  cursor: pointer;
  padding: 0.5em;
  border-width: 0;
}

html body form fieldset#custom div.select datalist div.option:hover,
html body form fieldset#custom div.select datalist div.option:focus,
html body form fieldset#custom div.select datalist div.option:checked {
  background-color: blue;
  color: white;
}

html
  body
  form
  fieldset#custom
  div.select
  div.optgroup
  div.option[data-disabled] {
  color: gray;
}

html
  body
  form
  fieldset#custom
  div.select
  div.optgroup
  div.option[data-checked] {
  background-color: blue;
  color: white;
}

html body form fieldset#custom div.select div.optgroup div.label {
  font-weight: bold;
}

html body form fieldset#custom div.select div.optgroup div.option div.label {
  font-weight: normal;
  padding: 0.25em;
}

html body form fieldset#custom div.select div.header span {
  flex: 1;
  padding: 0.5em;
}
2. Nó cũng có thể ghi đè một phần tử tổ tiên
body {
  font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif;
}

.select:focus {
  border-color: blue;
}

html body form fieldset#custom div.select[data-multiple] div.header {
  display: none;
}

html body form fieldset#custom div.select div.header {
  content: "↓";
  display: flex;
  flex: 1;
  align-items: center;
  padding: 0;
  position: relative;
  width: auto;
  box-sizing: border-box;
  border-width: 1px;
  border-style: inherit;
  border-color: inherit;
  border-radius: inherit;
}

html body form fieldset#custom div.select div.header::after {
  content: "↓";
  align-self: stretch;
  display: flex;
  align-content: center;
  justify-content: center;
  justify-items: center;
  align-items: center;
  padding: 0.5em;
}

html body form fieldset#custom div.select div.header:hover::after {
  background-color: blue;
}

.select .header select {
  appearance: none;
  font-family: inherit;
  font-size: inherit;
  padding: 0;
  border-width: 0;
  width: 100%;
  flex: 1;
  display: none;
}

.select .header select optgroup {
  display: none;
}

.select select div.option {
  display: none;
}

html body form fieldset#custom div.select {
  user-select: none;
  box-sizing: border-box;
  position: relative;
  border-radius: 4px;
  border-style: solid;
  border-width: 0;
  border-color: gray;
  width: auto;
  display: inline-block;
}

html body form fieldset#custom div.select:focus,
html body form fieldset#custom div.select:hover {
  border-color: blue;
}

html body form fieldset#custom div.select[data-open] {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

html body form fieldset#custom div.select[data-open] datalist {
  display: initial;
}

html body form fieldset#custom div.select datalist {
  appearance: none;
  position: absolute;
  border-style: solid;
  border-width: 1px;
  border-color: gray;
  left: 0;
  display: none;
  width: 100%;
  box-sizing: border-box;
  z-index: 2;
  border-bottom-left-radius: 4px;
  border-bottom-right-radius: 4px;
}

html body form fieldset#custom div.select datalist div.option {
  background-color: white;
  margin-bottom: 1px;
  cursor: pointer;
  padding: 0.5em;
  border-width: 0;
}

html body form fieldset#custom div.select datalist div.option:hover,
html body form fieldset#custom div.select datalist div.option:focus,
html body form fieldset#custom div.select datalist div.option:checked {
  background-color: blue;
  color: white;
}

html
  body
  form
  fieldset#custom
  div.select
  div.optgroup
  div.option[data-disabled] {
  color: gray;
}

html
  body
  form
  fieldset#custom
  div.select
  div.optgroup
  div.option[data-checked] {
  background-color: blue;
  color: white;
}

html body form fieldset#custom div.select div.optgroup div.label {
  font-weight: bold;
}

html body form fieldset#custom div.select div.optgroup div.option div.label {
  font-weight: normal;
  padding: 0.25em;
}

html body form fieldset#custom div.select div.header span {
  flex: 1;
  padding: 0.5em;
}
2

Thuộc tính Boolean này chỉ ra rằng có thể chọn nhiều tùy chọn trong danh sách. Nếu nó không được chỉ định, thì chỉ có thể chọn một tùy chọn tại một thời điểm. Khi

<label>Please choose one or more pets:
  <select name="pets" multiple size="4">
    <optgroup label="4-legged pets">
      <option value="dog">Dogoption>
      <option value="cat">Catoption>
      <option value="hamster" disabled>Hamsteroption>
    optgroup>
    <optgroup label="Flying pets">
      <option value="parrot">Parrotoption>
      <option value="macaw">Macawoption>
      <option value="albatross">Albatrossoption>
    optgroup>
  select>
label>
8 được chỉ định, hầu hết các trình duyệt sẽ hiển thị hộp danh sách cuộn thay vì một dòng thả xuống

Thuộc tính này được sử dụng để chỉ định tên của điều khiển

Một thuộc tính Boolean cho biết rằng phải chọn một tùy chọn có giá trị chuỗi không trống

Nếu điều khiển được trình bày dưới dạng hộp danh sách cuộn (e. g. khi

<label>Please choose one or more pets:
  <select name="pets" multiple size="4">
    <optgroup label="4-legged pets">
      <option value="dog">Dogoption>
      <option value="cat">Catoption>
      <option value="hamster" disabled>Hamsteroption>
    optgroup>
    <optgroup label="Flying pets">
      <option value="parrot">Parrotoption>
      <option value="macaw">Macawoption>
      <option value="albatross">Albatrossoption>
    optgroup>
  select>
label>
8 được chỉ định), thuộc tính này biểu thị số lượng hàng trong danh sách sẽ hiển thị cùng một lúc. Trình duyệt không bắt buộc phải trình bày phần tử được chọn dưới dạng hộp danh sách cuộn. Giá trị mặc định là
const selects = custom.querySelectorAll('select');
for (const select of selects) {
  const div = document.createElement('div');
  const header = document.createElement('div');
  const datalist = document.createElement('datalist');
  const optgroups = select.querySelectorAll('optgroup');
  const span = document.createElement('span');
  const options = select.options;
  const parent = select.parentElement;
  const multiple = select.hasAttribute('multiple');
  function onclick(e) {
    const disabled = this.hasAttribute('data-disabled');
    select.value = this.dataset.value;
    span.innerText = this.dataset.label;
    if (disabled) return;
    if (multiple) {
      if (e.shiftKey) {
        const checked = this.hasAttribute("data-checked");
        if (checked) {
          this.removeAttribute("data-checked");
        } else {
          this.setAttribute("data-checked", "");
        }
      } else {
        const options = div.querySelectorAll('.option');
        for (let i = 0; i < options.length; i++) {
          const option = options[i];
          option.removeAttribute("data-checked");
        }
        this.setAttribute("data-checked", "");
      }
    }
  }

  function onkeyup(e) {
    e.preventDefault();
    e.stopPropagation();
    if (e.keyCode === 13) {
      this.click();
    }
  }

  div.classList.add('select');
  header.classList.add('header');
  div.tabIndex = 1;
  select.tabIndex = -1;
  span.innerText = select.label;
  header.appendChild(span);

  for (const attribute of select.attributes) {
    div.dataset[attribute.name] = attribute.value;
  }
  for (let i = 0; i < options.length; i++) {
    const option = document.createElement('div');
    const label = document.createElement('div');
    const o = options[i];
    for (const attribute of o.attributes) {
      option.dataset[attribute.name] = attribute.value;
    }
    option.classList.add('option');
    label.classList.add('label');
    label.innerText = o.label;
    option.dataset.value = o.value;
    option.dataset.label = o.label;
    option.onclick = onclick;
    option.onkeyup = onkeyup;
    option.tabIndex = i + 1;
    option.appendChild(label);
    datalist.appendChild(option);
  }
  div.appendChild(header);
  for (const o of optgroups) {
    const optgroup = document.createElement('div');
    const label = document.createElement('div');
    const options = o.querySelectorAll('option');

    Object.assign(optgroup, o);
    optgroup.classList.add('optgroup');
    label.classList.add('label');
    label.innerText = o.label;
    optgroup.appendChild(label);
    div.appendChild(optgroup);
    for (const o of options) {
      const option = document.createElement('div');
      const label = document.createElement('div');

      for (const attribute of o.attributes) {
        option.dataset[attribute.name] = attribute.value;
      }
      option.classList.add('option');
      label.classList.add('label');
      label.innerText = o.label;
      option.tabIndex = i + 1;
      option.dataset.value = o.value;
      option.dataset.label = o.label;
      option.onclick = onclick;
      option.onkeyup = onkeyup;
      option.tabIndex = i + 1;
      option.appendChild(label);
      optgroup.appendChild(option);
    }
  }

  div.onclick = (e) => {
    e.preventDefault();
  };

  parent.insertBefore(div, select);
  header.appendChild(select);
  div.appendChild(datalist);
  datalist.style.top = `${header.offsetTop + header.offsetHeight}px`;

  div.onclick = (e) => {
    if (!multiple) {
      const open = this.hasAttribute("data-open");
      e.stopPropagation();
      if (open) {
        div.removeAttribute("data-open");
      } else {
        div.setAttribute("data-open", "");
      }
    }
  };

  div.onkeyup = (event) => {
    event.preventDefault();
    if (event.keyCode === 13) {
      div.click();
    }
  };

  document.addEventListener('click', (e) => {
    if (div.hasAttribute("data-open")) {
      div.removeAttribute("data-open");
    }
  });

  const width = Math.max(...Array.from(options).map((e) => {
    span.innerText = e.label;
    return div.offsetWidth;
  }));

  console.log(width);
  div.style.width = `${width}px`;
}
document.forms[0].onsubmit = (e) => {
  const data = new FormData(this);
  e.preventDefault();
  submit.innerText = JSON.stringify([...data.entries()]);
};
8

Ghi chú. Theo đặc tả HTML, giá trị mặc định cho kích thước phải là

const selects = custom.querySelectorAll('select');
for (const select of selects) {
  const div = document.createElement('div');
  const header = document.createElement('div');
  const datalist = document.createElement('datalist');
  const optgroups = select.querySelectorAll('optgroup');
  const span = document.createElement('span');
  const options = select.options;
  const parent = select.parentElement;
  const multiple = select.hasAttribute('multiple');
  function onclick(e) {
    const disabled = this.hasAttribute('data-disabled');
    select.value = this.dataset.value;
    span.innerText = this.dataset.label;
    if (disabled) return;
    if (multiple) {
      if (e.shiftKey) {
        const checked = this.hasAttribute("data-checked");
        if (checked) {
          this.removeAttribute("data-checked");
        } else {
          this.setAttribute("data-checked", "");
        }
      } else {
        const options = div.querySelectorAll('.option');
        for (let i = 0; i < options.length; i++) {
          const option = options[i];
          option.removeAttribute("data-checked");
        }
        this.setAttribute("data-checked", "");
      }
    }
  }

  function onkeyup(e) {
    e.preventDefault();
    e.stopPropagation();
    if (e.keyCode === 13) {
      this.click();
    }
  }

  div.classList.add('select');
  header.classList.add('header');
  div.tabIndex = 1;
  select.tabIndex = -1;
  span.innerText = select.label;
  header.appendChild(span);

  for (const attribute of select.attributes) {
    div.dataset[attribute.name] = attribute.value;
  }
  for (let i = 0; i < options.length; i++) {
    const option = document.createElement('div');
    const label = document.createElement('div');
    const o = options[i];
    for (const attribute of o.attributes) {
      option.dataset[attribute.name] = attribute.value;
    }
    option.classList.add('option');
    label.classList.add('label');
    label.innerText = o.label;
    option.dataset.value = o.value;
    option.dataset.label = o.label;
    option.onclick = onclick;
    option.onkeyup = onkeyup;
    option.tabIndex = i + 1;
    option.appendChild(label);
    datalist.appendChild(option);
  }
  div.appendChild(header);
  for (const o of optgroups) {
    const optgroup = document.createElement('div');
    const label = document.createElement('div');
    const options = o.querySelectorAll('option');

    Object.assign(optgroup, o);
    optgroup.classList.add('optgroup');
    label.classList.add('label');
    label.innerText = o.label;
    optgroup.appendChild(label);
    div.appendChild(optgroup);
    for (const o of options) {
      const option = document.createElement('div');
      const label = document.createElement('div');

      for (const attribute of o.attributes) {
        option.dataset[attribute.name] = attribute.value;
      }
      option.classList.add('option');
      label.classList.add('label');
      label.innerText = o.label;
      option.tabIndex = i + 1;
      option.dataset.value = o.value;
      option.dataset.label = o.label;
      option.onclick = onclick;
      option.onkeyup = onkeyup;
      option.tabIndex = i + 1;
      option.appendChild(label);
      optgroup.appendChild(option);
    }
  }

  div.onclick = (e) => {
    e.preventDefault();
  };

  parent.insertBefore(div, select);
  header.appendChild(select);
  div.appendChild(datalist);
  datalist.style.top = `${header.offsetTop + header.offsetHeight}px`;

  div.onclick = (e) => {
    if (!multiple) {
      const open = this.hasAttribute("data-open");
      e.stopPropagation();
      if (open) {
        div.removeAttribute("data-open");
      } else {
        div.setAttribute("data-open", "");
      }
    }
  };

  div.onkeyup = (event) => {
    event.preventDefault();
    if (event.keyCode === 13) {
      div.click();
    }
  };

  document.addEventListener('click', (e) => {
    if (div.hasAttribute("data-open")) {
      div.removeAttribute("data-open");
    }
  });

  const width = Math.max(...Array.from(options).map((e) => {
    span.innerText = e.label;
    return div.offsetWidth;
  }));

  console.log(width);
  div.style.width = `${width}px`;
}
document.forms[0].onsubmit = (e) => {
  const data = new FormData(this);
  e.preventDefault();
  submit.innerText = JSON.stringify([...data.entries()]);
};
9;

Trên máy tính để bàn, có một số cách để chọn nhiều tùy chọn trong phần tử (e. g. sử dụng Tab )

  • Chọn một mục ở trên cùng hoặc dưới cùng của phạm vi mà họ muốn chọn bằng cách sử dụng các phím con trỏ Lên và Xuống để đi lên và xuống các tùy chọn
  • Giữ phím Shift và sau đó sử dụng các phím con trỏ Lên và Xuống để tăng hoặc giảm phạm vi các mục đã chọn
  • Người dùng bàn phím có thể chọn nhiều mục không liền kề bằng cách

    • Tập trung vào yếu tố nổi tiếng là khó tạo kiểu hiệu quả bằng CSS. Bạn có thể tác động đến một số khía cạnh như bất kỳ yếu tố nào — ví dụ: thao tác với mô hình hộp, phông chữ được hiển thị, v.v. , và bạn có thể sử dụng thuộc tính 6

      Tuy nhiên, các thuộc tính này không tạo ra kết quả nhất quán trên các trình duyệt và rất khó để thực hiện những việc như sắp xếp các loại phần tử biểu mẫu khác nhau trong một cột với nhau. Cấu trúc bên trong của phần tử , hãy xem

      • Tạo kiểu biểu mẫu HTML
      • Kiểu dáng nâng cao cho biểu mẫu HTML

      Ngoài ra, hãy xem ví dụ "Tùy chỉnh kiểu chọn" bên dưới để biết ví dụ về việc bạn có thể thử tạo kiểu

      Ví dụ này về cơ bản

      • Sao chép bối cảnh của 9 đến id0 của các phần tử mới để quản lý trạng thái và CSS

      Ghi chú. Không phải tất cả các tính năng gốc đều được hỗ trợ, đó là Bằng chứng về khái niệm. CNTT bắt đầu từ HTML tiêu chuẩn nhưng có thể đạt được kết quả tương tự khi bắt đầu từ dữ liệu JSON, HTML tùy chỉnh hoặc các giải pháp khác

      HTML

      <form>
        <fieldset>
          <legend>Standard controlslegend>
          <select name="1A" id="select" autocomplete="off" required>
            <option>Carrotsoption>
            <option>Peasoption>
            <option>Beansoption>
            <option>Pneumonoultramicroscopicsilicovolcanoconiosisoption>
          select>
        fieldset>
        <fieldset id="custom">
          <legend>Custom controlslegend>
          <select name="2A" id="select" autocomplete="off" required>
            <option>Carrotsoption>
            <option>Peasoption>
            <option>Beansoption>
            <option>Pneumonoultramicroscopicsilicovolcanoconiosisoption>
          select>
        fieldset>
      form>
      

      CSS

      body {
        font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif;
      }
      
      .select:focus {
        border-color: blue;
      }
      
      html body form fieldset#custom div.select[data-multiple] div.header {
        display: none;
      }
      
      html body form fieldset#custom div.select div.header {
        content: "↓";
        display: flex;
        flex: 1;
        align-items: center;
        padding: 0;
        position: relative;
        width: auto;
        box-sizing: border-box;
        border-width: 1px;
        border-style: inherit;
        border-color: inherit;
        border-radius: inherit;
      }
      
      html body form fieldset#custom div.select div.header::after {
        content: "↓";
        align-self: stretch;
        display: flex;
        align-content: center;
        justify-content: center;
        justify-items: center;
        align-items: center;
        padding: 0.5em;
      }
      
      html body form fieldset#custom div.select div.header:hover::after {
        background-color: blue;
      }
      
      .select .header select {
        appearance: none;
        font-family: inherit;
        font-size: inherit;
        padding: 0;
        border-width: 0;
        width: 100%;
        flex: 1;
        display: none;
      }
      
      .select .header select optgroup {
        display: none;
      }
      
      .select select div.option {
        display: none;
      }
      
      html body form fieldset#custom div.select {
        user-select: none;
        box-sizing: border-box;
        position: relative;
        border-radius: 4px;
        border-style: solid;
        border-width: 0;
        border-color: gray;
        width: auto;
        display: inline-block;
      }
      
      html body form fieldset#custom div.select:focus,
      html body form fieldset#custom div.select:hover {
        border-color: blue;
      }
      
      html body form fieldset#custom div.select[data-open] {
        border-bottom-left-radius: 0;
        border-bottom-right-radius: 0;
      }
      
      html body form fieldset#custom div.select[data-open] datalist {
        display: initial;
      }
      
      html body form fieldset#custom div.select datalist {
        appearance: none;
        position: absolute;
        border-style: solid;
        border-width: 1px;
        border-color: gray;
        left: 0;
        display: none;
        width: 100%;
        box-sizing: border-box;
        z-index: 2;
        border-bottom-left-radius: 4px;
        border-bottom-right-radius: 4px;
      }
      
      html body form fieldset#custom div.select datalist div.option {
        background-color: white;
        margin-bottom: 1px;
        cursor: pointer;
        padding: 0.5em;
        border-width: 0;
      }
      
      html body form fieldset#custom div.select datalist div.option:hover,
      html body form fieldset#custom div.select datalist div.option:focus,
      html body form fieldset#custom div.select datalist div.option:checked {
        background-color: blue;
        color: white;
      }
      
      html
        body
        form
        fieldset#custom
        div.select
        div.optgroup
        div.option[data-disabled] {
        color: gray;
      }
      
      html
        body
        form
        fieldset#custom
        div.select
        div.optgroup
        div.option[data-checked] {
        background-color: blue;
        color: white;
      }
      
      html body form fieldset#custom div.select div.optgroup div.label {
        font-weight: bold;
      }
      
      html body form fieldset#custom div.select div.optgroup div.option div.label {
        font-weight: normal;
        padding: 0.25em;
      }
      
      html body form fieldset#custom div.select div.header span {
        flex: 1;
        padding: 0.5em;
      }
      

      JavaScript

      const selects = custom.querySelectorAll('select');
      for (const select of selects) {
        const div = document.createElement('div');
        const header = document.createElement('div');
        const datalist = document.createElement('datalist');
        const optgroups = select.querySelectorAll('optgroup');
        const span = document.createElement('span');
        const options = select.options;
        const parent = select.parentElement;
        const multiple = select.hasAttribute('multiple');
        function onclick(e) {
          const disabled = this.hasAttribute('data-disabled');
          select.value = this.dataset.value;
          span.innerText = this.dataset.label;
          if (disabled) return;
          if (multiple) {
            if (e.shiftKey) {
              const checked = this.hasAttribute("data-checked");
              if (checked) {
                this.removeAttribute("data-checked");
              } else {
                this.setAttribute("data-checked", "");
              }
            } else {
              const options = div.querySelectorAll('.option');
              for (let i = 0; i < options.length; i++) {
                const option = options[i];
                option.removeAttribute("data-checked");
              }
              this.setAttribute("data-checked", "");
            }
          }
        }
      
        function onkeyup(e) {
          e.preventDefault();
          e.stopPropagation();
          if (e.keyCode === 13) {
            this.click();
          }
        }
      
        div.classList.add('select');
        header.classList.add('header');
        div.tabIndex = 1;
        select.tabIndex = -1;
        span.innerText = select.label;
        header.appendChild(span);
      
        for (const attribute of select.attributes) {
          div.dataset[attribute.name] = attribute.value;
        }
        for (let i = 0; i < options.length; i++) {
          const option = document.createElement('div');
          const label = document.createElement('div');
          const o = options[i];
          for (const attribute of o.attributes) {
            option.dataset[attribute.name] = attribute.value;
          }
          option.classList.add('option');
          label.classList.add('label');
          label.innerText = o.label;
          option.dataset.value = o.value;
          option.dataset.label = o.label;
          option.onclick = onclick;
          option.onkeyup = onkeyup;
          option.tabIndex = i + 1;
          option.appendChild(label);
          datalist.appendChild(option);
        }
        div.appendChild(header);
        for (const o of optgroups) {
          const optgroup = document.createElement('div');
          const label = document.createElement('div');
          const options = o.querySelectorAll('option');
      
          Object.assign(optgroup, o);
          optgroup.classList.add('optgroup');
          label.classList.add('label');
          label.innerText = o.label;
          optgroup.appendChild(label);
          div.appendChild(optgroup);
          for (const o of options) {
            const option = document.createElement('div');
            const label = document.createElement('div');
      
            for (const attribute of o.attributes) {
              option.dataset[attribute.name] = attribute.value;
            }
            option.classList.add('option');
            label.classList.add('label');
            label.innerText = o.label;
            option.tabIndex = i + 1;
            option.dataset.value = o.value;
            option.dataset.label = o.label;
            option.onclick = onclick;
            option.onkeyup = onkeyup;
            option.tabIndex = i + 1;
            option.appendChild(label);
            optgroup.appendChild(option);
          }
        }
      
        div.onclick = (e) => {
          e.preventDefault();
        };
      
        parent.insertBefore(div, select);
        header.appendChild(select);
        div.appendChild(datalist);
        datalist.style.top = `${header.offsetTop + header.offsetHeight}px`;
      
        div.onclick = (e) => {
          if (!multiple) {
            const open = this.hasAttribute("data-open");
            e.stopPropagation();
            if (open) {
              div.removeAttribute("data-open");
            } else {
              div.setAttribute("data-open", "");
            }
          }
        };
      
        div.onkeyup = (event) => {
          event.preventDefault();
          if (event.keyCode === 13) {
            div.click();
          }
        };
      
        document.addEventListener('click', (e) => {
          if (div.hasAttribute("data-open")) {
            div.removeAttribute("data-open");
          }
        });
      
        const width = Math.max(...Array.from(options).map((e) => {
          span.innerText = e.label;
          return div.offsetWidth;
        }));
      
        console.log(width);
        div.style.width = `${width}px`;
      }
      document.forms[0].onsubmit = (e) => {
        const data = new FormData(this);
        e.preventDefault();
        submit.innerText = JSON.stringify([...data.entries()]);
      };
      

      Kết quả

    Danh mục nội dung, , , , , và phần tửNội dung được phépKhông hoặc nhiều hơn

    <label>Please choose one or more pets:
      <select name="pets" multiple size="4">
        <optgroup label="4-legged pets">
          <option value="dog">Dogoption>
          <option value="cat">Catoption>
          <option value="hamster" disabled>Hamsteroption>
        optgroup>
        <optgroup label="Flying pets">
          <option value="parrot">Parrotoption>
          <option value="macaw">Macawoption>
          <option value="albatross">Albatrossoption>
        optgroup>
      select>
    label>
    
    0 hoặc
    <form>
      <fieldset>
        <legend>Standard controlslegend>
        <select name="1A" id="select" autocomplete="off" required>
          <option>Carrotsoption>
          <option>Peasoption>
          <option>Beansoption>
          <option>Pneumonoultramicroscopicsilicovolcanoconiosisoption>
        select>
      fieldset>
      <fieldset id="custom">
        <legend>Custom controlslegend>
        <select name="2A" id="select" autocomplete="off" required>
          <option>Carrotsoption>
          <option>Peasoption>
          <option>Beansoption>
          <option>Pneumonoultramicroscopicsilicovolcanoconiosisoption>
        select>
      fieldset>
    form>
    
    4 phần tử. Bỏ sót thẻKhông có, cả thẻ bắt đầu và thẻ kết thúc đều bắt buộc. Cha mẹ được phép Bất kỳ phần tử nào chấp nhận. Vai trò ARIA ngầm địnhid3 không có thuộc tính
    <label>Please choose one or more pets:
      <select name="pets" multiple size="4">
        <optgroup label="4-legged pets">
          <option value="dog">Dogoption>
          <option value="cat">Catoption>
          <option value="hamster" disabled>Hamsteroption>
        optgroup>
        <optgroup label="Flying pets">
          <option value="parrot">Parrotoption>
          <option value="macaw">Macawoption>
          <option value="albatross">Albatrossoption>
        optgroup>
      select>
    label>
    
    8 và không có thuộc tính
    <label>Please choose one or more pets:
      <select name="pets" multiple size="4">
        <optgroup label="4-legged pets">
          <option value="dog">Dogoption>
          <option value="cat">Catoption>
          <option value="hamster" disabled>Hamsteroption>
        optgroup>
        <optgroup label="Flying pets">
          <option value="parrot">Parrotoption>
          <option value="macaw">Macawoption>
          <option value="albatross">Albatrossoption>
        optgroup>
      select>
    label>
    
    9 nào lớn hơn 1, nếu không thì id6Các vai trò ARIA được phépid7 không có thuộc tính
    <label>Please choose one or more pets:
      <select name="pets" multiple size="4">
        <optgroup label="4-legged pets">
          <option value="dog">Dogoption>
          <option value="cat">Catoption>
          <option value="hamster" disabled>Hamsteroption>
        optgroup>
        <optgroup label="Flying pets">
          <option value="parrot">Parrotoption>
          <option value="macaw">Macawoption>
          <option value="albatross">Albatrossoption>
        optgroup>
      select>
    label>
    
    8 và không có thuộc tính
    <label>Please choose one or more pets:
      <select name="pets" multiple size="4">
        <optgroup label="4-legged pets">
          <option value="dog">Dogoption>
          <option value="cat">Catoption>
          <option value="hamster" disabled>Hamsteroption>
        optgroup>
        <optgroup label="Flying pets">
          <option value="parrot">Parrotoption>
          <option value="macaw">Macawoption>
          <option value="albatross">Albatrossoption>
        optgroup>
      select>
    label>
    
    9 nào lớn hơn 1, nếu không thì không có giao diện 0 cho phépDOM_______47_______1

    Hộp tổ hợp trong HTML là gì?

    Hộp tổ hợp về cơ bản là ĐẦU VÀO HTML của loại văn bản và CHỌN HTML được nhóm lại với nhau để cung cấp cho bạn chức năng của hộp tổ hợp . Bạn có thể đặt văn bản trong điều khiển INPUT bằng cách sử dụng điều khiển SELECT hoặc nhập trực tiếp vào trường văn bản. Trong ví dụ này, CHỌN sẽ được điền từ thuộc tính id=year.

    Sự khác biệt giữa ComboBox và thả xuống trong HTML là gì?

    Danh sách thả xuống là danh sách trong đó mục đã chọn luôn hiển thị và các mục khác hiển thị theo yêu cầu bằng cách nhấp vào nút thả xuống. Hộp tổ hợp là sự kết hợp của hộp danh sách tiêu chuẩn hoặc danh sách thả xuống và hộp văn bản có thể chỉnh sửa, do đó cho phép người dùng nhập một giá trị không có trong danh sách.

    Thẻ chính xác để nhận hộp tổ hợp hoặc danh sách thả xuống để nhập vào trong HTML là gì?

    name: The HTML