MVC中submit提交按钮点击后触发JS设置文本框只读的方法
核心原因
你遇到的逻辑失效本质是时序错位和场景不匹配,和按钮是不是submit类型没有直接绑定关系:
- 当按钮保持
type="submit"时,点击会直接触发表单原生提交流程:如果是传统MVC的同步提交,页面会立刻重载,你在JS内存里临时设置的readOnly状态会随着页面重载直接丢失,自然看不到效果。 - 你之前把按钮改成
type="button"就能看到只读效果,本质是这种按钮本身不会触发原生表单提交,页面不会跳转/刷新,你在DOM上设置的只读状态自然能保留——但这种方式等于直接掐断了表单的核心提交功能,是“为了看效果牺牲功能”的假生效。 - 你原来的JS选择器
document.querySelectorAll('input')会把提交按钮本身也纳入只读设置范围,本身也不符合“仅给表单内文本框设只读”的需求。
分场景调整方案
结合你用MVC框架的实际开发场景,按你的提交方式选对应方案即可:
场景1:AJAX无刷新提交(提交后不跳转,当前DOM保留)
把原来绑在按钮onclick上的逻辑,迁移到表单的submit事件回调中,确保设置只读的动作发生在提交动作发起之前,同时精准筛选需要设置只读的文本类输入控件:
// 给实际的搜索表单绑定提交事件,不要只绑按钮的点击事件 const searchForm = document.getElementById("你的搜索表单DOM的id"); searchForm.addEventListener("submit", function () { // 仅筛选表单内的文本类输入控件,排除按钮、单选框、复选框等非文本元素 const textInputs = searchForm.querySelectorAll( 'input[type="text"], input[type="search"], input[type="password"], textarea' ); // 批量设置只读 textInputs.forEach(input => { input.readOnly = true; }); // 这里再接你的AJAX提交逻辑:如果用AJAX无刷新提交,就加上下面这行阻止原生跳转 // e.preventDefault(); // 原来的AJAX请求代码... })
这种写法的额外好处是:即使用户在输入框按回车键触发提交,也会正常执行只读设置,不会漏触发逻辑。
场景2:传统MVC同步提交(提交后页面刷新/跳转,由服务器返回新视图)
这种场景下纯前端JS设置只读是完全无效的——因为页面重载后所有DOM都是服务器重新渲染返回的,前端JS在内存里改的临时状态根本无法跨页面传递。
正确的实现方式要结合MVC的视图渲染逻辑:
- 在提交表单对应的Controller Action里,处理完提交逻辑后,通过
TempData存储一个提交完成的临时标记,比如:[HttpPost] public IActionResult Search(SearchModel model) { // 原有提交处理逻辑... TempData["SearchSubmitted"] = true; return View(model); } - 在对应视图里,根据这个标记动态给文本框加只读属性,以Razor视图为例:
<input type="text" name="searchKey" value="@Model.SearchKey" @(TempData["SearchSubmitted"] != null ? "readonly" : "") />
这样提交完成后,服务器返回的视图本身就自带只读属性,哪怕页面刷新也能稳定保持状态,不需要依赖前端JS的临时修改。
注意:
readOnly属性的输入框会正常随表单携带值提交,和disabled属性不同——设置为disabled的输入框内容不会被提交到后端,开发时注意不要搞混两个属性的作用。
内容的提问来源于stack exchange,提问作者shimaa_nabil
相关产品推荐
相关产品推荐

