在网页表单开发中,经常会遇到需要给输入框设置固定前缀并且禁止用户编辑前缀,同时允许用户填写后续内容的需求,比如手机号区号、订单编号前缀等场景。这种需求不能直接使用readonly或者disabled属性,因为这两个属性会让整个输入框都无法编辑,不符合用户可填写后续内容的要求。

方案一:使用两个输入框拼接实现
这种方案的核心思路是将前缀和后续输入内容分成两个输入框,前缀输入框设置为只读,后续输入框正常可编辑,再通过CSS让两个输入框看起来像一个整体。首先看HTML结构:
<div class="input-group"> <input type="text" class="prefix-input" value="+86" readonly> <input type="text" class="content-input" placeholder="请输入手机号"> </div>
接下来是CSS样式,用来消除两个输入框之间的间隙,让它们看起来是一个完整的输入框:
.input-group {
display: inline-flex;
border: 1px solid #ccc;
border-radius: 4px;
overflow: hidden;
}
.prefix-input {
width: 50px;
padding: 8px 12px;
border: none;
background-color: #f5f5f5;
text-align: center;
}
.content-input {
flex: 1;
padding: 8px 12px;
border: none;
outline: none;
}
/* 聚焦时整体边框高亮 */
.input-group:focus-within {
border-color: #409eff;
}
这种方案的优势是兼容性极好,所有浏览器都支持,逻辑简单清晰,缺点是样式调整需要花费一定精力,并且提交表单时需要同时获取两个输入框的值进行拼接。
方案二:使用单个输入框配合事件监听
这种方案只使用一个<input>标签,通过监听输入事件,限制用户不能修改前缀部分的内容。首先定义HTML结构:
<input type="text" id="phoneInput" value="+86 " placeholder="请输入手机号">
接下来是JavaScript逻辑,监听input事件,判断用户是否修改了前缀部分,如果修改了就自动恢复前缀:
const phoneInput = document.getElementById('phoneInput');
// 定义固定的前缀内容
const prefix = '+86 ';
// 初始化时设置输入框值
phoneInput.value = prefix;
phoneInput.addEventListener('input', function(e) {
// 获取当前输入框的值
const currentVal = e.target.value;
// 如果当前值不以固定前缀开头,或者前缀部分被修改,就强制恢复前缀
if (!currentVal.startsWith(prefix)) {
e.target.value = prefix + currentVal.replace(prefix, '');
}
// 保存光标位置,避免用户编辑时光标跳转到末尾
const cursorPos = e.target.selectionStart;
// 如果光标位置在前缀长度范围内,就把光标移到前缀后面
if (cursorPos < prefix.length) {
e.target.setSelectionRange(prefix.length, prefix.length);
}
});
// 监听keydown事件,禁止用户删除前缀部分的内容
phoneInput.addEventListener('keydown', function(e) {
const cursorPos = e.target.selectionStart;
// 如果光标在前缀范围内,并且按的是删除键或者退格键,就阻止默认行为
if (cursorPos <= prefix.length && (e.key === 'Backspace' || e.key === 'Delete')) {
e.preventDefault();
}
});
这种方案只需要一个输入框,提交表单时直接获取值即可,不需要拼接,但是需要处理光标位置和键盘事件,逻辑相对复杂一些,并且如果用户复制粘贴内容可能会绕过部分限制,需要做额外的校验。
方案三:使用contenteditable属性模拟输入框
还可以使用contenteditable属性将普通元素设置为可编辑状态,把前缀部分设置为不可编辑,后续部分可编辑。HTML结构如下:
<div class="custom-input" contenteditable="true"> <span class="fixed-prefix" contenteditable="false">+86 </span> <span class="editable-content"></span> </div>
对应的CSS样式:
.custom-input {
border: 1px solid #ccc;
border-radius: 4px;
padding: 8px 12px;
min-height: 36px;
line-height: 20px;
outline: none;
}
.custom-input:focus {
border-color: #409eff;
}
.fixed-prefix {
color: #666;
user-select: none;
}
.editable-content {
outline: none;
}
这种方案的优势是样式调整灵活,但是获取输入内容时需要处理DOM节点,兼容性稍差,并且表单提交时需要额外获取内容,不适合对兼容性要求高的场景。
方案选择建议
如果项目对兼容性要求高,优先选择两个输入框拼接的方案,逻辑简单不容易出问题。如果希望减少表单元素数量,可选择单个输入框配合事件监听的方案,注意做好边界情况的处理。如果页面样式要求高,且不需要兼容太老的浏览器,可选择contenteditable模拟的方案。
需要注意的是,前端做的限制都可以通过开发者工具修改,如果对数据安全性要求高,后端也需要做对应的校验,避免用户提交不符合要求的内容。
HTMLinputreadonlydisabledcontenteditable修改时间:2026-06-18 17:15:36