在 ASP.NET 開發中,有時需要讓下拉式選單(DropDownList)呈現唯讀狀態,既保留選中的值供用戶查看,又防止用戶誤更改選項。標準 HTML 的 <select> 元素並無原生 readonly 屬性,僅支援 disabled,但停用後表單不會提交該控件的值。本文介紹兩種實用技巧:純 JavaScript 方案與 ASP.NET 伺服器端屬性注入方案,幫助你輕鬆實現「可見、不可改、可提交」的唯讀下拉選單。
透過攔截滑鼠事件與焦點事件,模擬唯讀行為。核心邏輯:滑鼠移入時捕獲滑鼠事件(setCapture),移出時釋放(releaseCapture),獲得焦點時立即失焦(blur),並在啟用前攔截(onbeforeactivate 返回 false)。
<script type="text/javascript">
// 根據容器 ID 設定內部下拉框為唯讀
function setReadOnly(containerId) {
var container = document.getElementById(containerId);
var select = container.getElementsByTagName('select')[0];
if (!select) return;
select.onmouseover = function () { this.setCapture(); };
select.onmouseout = function () { this.releaseCapture(); };
select.onfocus = function () { this.blur(); };
select.onbeforeactivate = function () { return false; };
}
</script>
<span id="span_select">
<select id="id_select">
<option value="1">選項一</option>
<option value="2">選項二</option>
<option value="3">選項三</option>
</select>
</span>
<script type="text/javascript">
setReadOnly("span_select");
</script>
此法優點在於不修改原始 <select> 標籤,透過外層容器統一管理,適合既有頁面快速套用。
在 Page_Load 或控件初始化階段,直接為 DropDownList 注入客戶端事件屬性,程式碼更精簡、維護性更高:
// C# 後台代碼
this.ddlSysCategory.Attributes.Add("onfocus", "this.blur();");
this.ddlSysCategory.Attributes.Add("onbeforeactivate", "return false");
this.ddlSysCategory.Attributes.Add("onmouseover", "this.setCapture()");
this.ddlSysCategory.Attributes.Add("onmouseout", "this.releaseCapture()");
等同於在前端直接撰寫:
<select onbeforeactivate="return false"
onfocus="this.blur()"
onmouseover="this.setCapture()"
onmouseout="this.releaseCapture()">
<option value="1">選項一</option>
<option value="2">選項二</option>
</select>
disabled 則不會。setCapture/releaseCapture 為 IE 專屬,現代瀏覽器建議改用 pointer-events: none CSS 配合 tabindex="-1" 實現更標準的唯讀效果。aria-readonly="true" 提升螢幕閱讀器體驗。若專案支援現代瀏覽器,建議採用純 CSS 方案,無需 JavaScript:
.dropdown-readonly {
pointer-events: none; /* 禁止滑鼠互動 */
opacity: 0.65; /* 視覺提示不可編輯 */
background-color: #f5f5f5; /* 模擬停用狀態背景 */
}
<select class="dropdown-readonly" tabindex="-1" aria-readonly="true">
<option value="1" selected>已選項目</option>
<option value="2">其他項目</option>
</select>
此法語意更清晰、效能更佳,且自動應用於所有符合條件的下拉選單。