You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现带内嵌文本编辑框的单选按钮组?

带内嵌输入框的单选按钮组实现方案

基础HTML/CSS/JS实现

适合无框架场景,核心是将单选按钮与输入框绑定为同一交互单元,通过CSS规整布局,JS处理状态逻辑:

结构代码

<div class="size-filter-group">
  <label class="radio-option">
    <input type="radio" name="sizeFilter" value="no-limit" checked>
    <span>无大小限制</span>
  </label>

  <label class="radio-option">
    <input type="radio" name="sizeFilter" value="max-size">
    <span>最大大小:</span>
    <input type="number" class="size-input" placeholder="KB" disabled>
  </label>

  <label class="radio-option">
    <input type="radio" name="sizeFilter" value="min-size">
    <span>最小大小:</span>
    <input type="number" class="size-input" placeholder="KB" disabled>
  </label>

  <label class="radio-option">
    <input type="radio" name="sizeFilter" value="size-range">
    <span>大小范围:</span>
    <input type="number" class="size-input" placeholder="最小KB" disabled>
    <span> - </span>
    <input type="number" class="size-input" placeholder="最大KB" disabled>
  </label>
</div>

样式调整(CSS)

.size-filter-group {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px;
}

.radio-option {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

.size-input {
  width: 80px;
  padding: 4px 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.size-input:disabled {
  background-color: #f5f5f5;
  cursor: not-allowed;
}

交互逻辑(JS)

const radioInputs = document.querySelectorAll('input[name="sizeFilter"]');
const sizeInputs = document.querySelectorAll('.size-input');

radioInputs.forEach(radio => {
  radio.addEventListener('change', () => {
    // 先禁用所有输入框
    sizeInputs.forEach(input => input.disabled = true);
    
    // 根据选中项启用对应输入框
    const selectedValue = radio.value;
    if (selectedValue === 'max-size' || selectedValue === 'min-size') {
      radio.parentElement.querySelector('.size-input').disabled = false;
    } else if (selectedValue === 'size-range') {
      radio.parentElement.querySelectorAll('.size-input').forEach(input => input.disabled = false);
    }
  });
});

// 提交时的参数处理示例
function handleSubmit() {
  const selectedRadio = document.querySelector('input[name="sizeFilter"]:checked');
  let filterParams = {};
  
  switch(selectedRadio.value) {
    case 'no-limit':
      filterParams.size = null;
      break;
    case 'max-size':
      const maxSize = selectedRadio.parentElement.querySelector('.size-input').value;
      filterParams.maxSize = maxSize ? parseInt(maxSize) : null;
      break;
    case 'min-size':
      const minSize = selectedRadio.parentElement.querySelector('.size-input').value;
      filterParams.minSize = minSize ? parseInt(minSize) : null;
      break;
    case 'size-range':
      const [rangeMin, rangeMax] = selectedRadio.parentElement.querySelectorAll('.size-input');
      filterParams.sizeRange = {
        min: rangeMin.value ? parseInt(rangeMin.value) : null,
        max: rangeMax.value ? parseInt(rangeMax.value) : null
      };
      break;
  }
  
  // 将参数传入后台查询逻辑
  console.log('筛选参数:', filterParams);
}

React组件实现

基于React的状态管理,逻辑更简洁可控:

import { useState } from 'react';

const SizeFilter = () => {
  const [selectedOption, setSelectedOption] = useState('no-limit');
  const [maxSize, setMaxSize] = useState('');
  const [minSize, setMinSize] = useState('');
  const [rangeMin, setRangeMin] = useState('');
  const [rangeMax, setRangeMax] = useState('');

  const handleRadioChange = (e) => {
    setSelectedOption(e.target.value);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    let filterParams = {};
    switch(selectedOption) {
      case 'no-limit':
        filterParams.size = null;
        break;
      case 'max-size':
        filterParams.maxSize = maxSize ? parseInt(maxSize) : null;
        break;
      case 'min-size':
        filterParams.minSize = minSize ? parseInt(minSize) : null;
        break;
      case 'size-range':
        filterParams.sizeRange = {
          min: rangeMin ? parseInt(rangeMin) : null,
          max: rangeMax ? parseInt(rangeMax) : null
        };
        break;
    }
    // 提交到后台查询
    console.log('筛选参数:', filterParams);
  };

  return (
    <form onSubmit={handleSubmit} className="size-filter-group">
      <label className="radio-option">
        <input
          type="radio"
          name="sizeFilter"
          value="no-limit"
          checked={selectedOption === 'no-limit'}
          onChange={handleRadioChange}
        />
        <span>无大小限制</span>
      </label>

      <label className="radio-option">
        <input
          type="radio"
          name="sizeFilter"
          value="max-size"
          checked={selectedOption === 'max-size'}
          onChange={handleRadioChange}
        />
        <span>最大大小:</span>
        <input
          type="number"
          className="size-input"
          placeholder="KB"
          disabled={selectedOption !== 'max-size'}
          value={maxSize}
          onChange={(e) => setMaxSize(e.target.value)}
        />
      </label>

      <label className="radio-option">
        <input
          type="radio"
          name="sizeFilter"
          value="min-size"
          checked={selectedOption === 'min-size'}
          onChange={handleRadioChange}
        />
        <span>最小大小:</span>
        <input
          type="number"
          className="size-input"
          placeholder="KB"
          disabled={selectedOption !== 'min-size'}
          value={minSize}
          onChange={(e) => setMinSize(e.target.value)}
        />
      </label>

      <label className="radio-option">
        <input
          type="radio"
          name="sizeFilter"
          value="size-range"
          checked={selectedOption === 'size-range'}
          onChange={handleRadioChange}
        />
        <span>大小范围:</span>
        <input
          type="number"
          className="size-input"
          placeholder="最小KB"
          disabled={selectedOption !== 'size-range'}
          value={rangeMin}
          onChange={(e) => setRangeMin(e.target.value)}
        />
        <span> - </span>
        <input
          type="number"
          className="size-input"
          placeholder="最大KB"
          disabled={selectedOption !== 'size-range'}
          value={rangeMax}
          onChange={(e) => setRangeMax(e.target.value)}
        />
      </label>

      <button type="submit">应用筛选</button>
    </form>
  );
};

export default SizeFilter;

关键注意事项

  • 输入校验:添加数字格式、非空校验(选中对应选项时),比如范围选项需确保最小值不大于最大值。
  • 可访问性:用label包裹单选与输入框,添加合适的aria属性,符合WCAG标准。
  • 样式适配:可根据项目UI规范调整布局(比如横向排列选项)和样式细节。

内容的提问来源于stack exchange,提问作者Syzygy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 23:06:20