根据HTML规范,HTML中的select标签没有readonly属性,只有disabled属性。所以如果你想让用户不改变下拉菜单,你必须使用disabled。

唯一的问题是禁用的HTML表单输入不会包含在POST / get数据中。

什么是最好的方法来模拟一个选择标签的只读属性,仍然得到POST数据?


当前回答

您应该禁用select元素,但同时添加另一个具有相同名称和值的隐藏输入。

如果您重新启用SELECT,您应该将其值复制到onchange事件中的隐藏输入,并禁用(或删除)隐藏输入。

下面是一个演示:

$('#mainform').submit(function() { $('#formdata_container').show(); $('#formdata').html($(this).serialize()); return false; }); $('#enableselect').click(function() { $('#mainform input[name=animal]') .attr("disabled", true); $('#animal-select') .attr('disabled', false) .attr('name', 'animal'); $('#enableselect').hide(); return false; }); #formdata_container { padding: 10px; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div> <form id="mainform"> <select id="animal-select" disabled="true"> <option value="cat" selected>Cat</option> <option value="dog">Dog</option> <option value="hamster">Hamster</option> </select> <input type="hidden" name="animal" value="cat"/> <button id="enableselect">Enable</button> <select name="color"> <option value="blue" selected>Blue</option> <option value="green">Green</option> <option value="red">Red</option> </select> <input type="submit"/> </form> </div> <div id="formdata_container" style="display:none"> <div>Submitted data:</div> <div id="formdata"> </div> </div>

其他回答

我知道这不会帮助每个人(如果你只是客户端),但会帮助一些全栈和控制后端以及前端的人。

如果用户没有编辑字段的特权,我只返回下拉列表的当前选择。

以下是我的后端控制器:

        #region Prepare Action Priviledges
        editAuditVM.ExtAuditEditRoleMatrixVM = new ExtAuditEditRoleMatrixVM
        {
            CanEditAcn = _extAuditEditRoleMatrixHelper.CanEditAcn(user, audit),
            CanEditSensitiveDesignation = _extAuditEditRoleMatrixHelper.CanEditSensitiveDesignation(user, audit),
            CanEditTitle = _extAuditEditRoleMatrixHelper.CanEditTitle(),
            CanEditAuditScope = _extAuditEditRoleMatrixHelper.CanEditAuditScope(user, audit)
        };
        #endregion


        #region Prepare SelectLists for Drop Downs
        #region AuditScope List
        IQueryable<SelectListItem> auditScopes = _auditTypesRepo.AuditTypes
            .Where(at => at.AuditTypeClassCode.ToLower() == "e")
            .Select(at => new SelectListItem
            { Text = at.AuditTypeText, Value = at.AuditTypeID.ToString() });
        // Cannot make a select readonly on client side.
        //  So only return currently selected option.
        if (!editAuditVM.ExtAuditEditRoleMatrixVM.CanEditAuditScope)
        {
            auditScopes = auditScopes
                .Where(ascopeId => ascopeId.Value == editAuditVM.ExternalAudit.AuditTypeID.ToString());
        }
        #endregion
        #endregion
    var selectedOpt;//initialize var
    var newIdForHidden;//initialize var
    $('.disabledOnEdit').focusin(function(){
        selectedOpt = $(this).find(":selected").val();
        newIdForHidden = $(this).attr('id')+'Hidden';
        //alert(selectedOpt+','+newIdForHidden);
        $(this).append('');
        $(this).find('input.hiddenSelectedOpt').attr('id',newIdForHidden).val(selectedOpt);
    });
    $('.disabledOnEdit').focusout(function(){
        var oldSelectedValue=$(this).find('input.hiddenSelectedOpt').val();
        $(this).val(oldSelectedValue);
    });

(简单的解决方案)

由于OP特别要求他不想禁用select元素,下面是我用来使select变为只读的方法

在html中

<select style="pointer-events: none;" onclick="return false;" onkeydown="return false;" ></select>

就是这样

解释

将pointer-events设置为none将禁用使用鼠标/光标事件编辑“select-element” 设置onclick和onkeydown函数返回false将禁用使用键盘编辑“select-element”

通过这种方式,您不必创建任何额外的元素,或使用javascript禁用/重新启用元素,或打乱表单提交逻辑,或使用任何第三方库。

此外,您可以轻松地添加css样式,如设置背景颜色为灰色或文本颜色为灰色,以暗示该元素是只读的。我没有将它添加到代码中,因为它非常特定于您的站点主题

或者你想通过javascript来实现

let isReadOnly = true; selectElement。Onclick = function () { isReadOnly; }; selectElement。onkeydown = function () { isReadOnly; }; selectElement.style.pointerEvents = isReadOnly ?“none”:“全部”;

如果选择下拉菜单自诞生以来是只读的,根本不需要更改,也许您应该使用另一个控件?比如一个简单的<div>(加上隐藏的表单字段)或一个<input type="text">?

补充:如果下拉菜单不是一直都是只读的,并且JavaScript被用来启用/禁用它,那么这仍然是一个解决方案——只需要动态修改DOM。

除了禁用不应该是可选的选项,我想实际上让他们从列表中消失,但仍然能够启用他们,我应该以后需要:

$("select[readonly]").find("option:not(:selected)").hide().attr("disabled",true);

它会找到所有带有只读属性的select元素,然后找到那些未被选中的select元素中的所有选项,然后隐藏它们并禁用它们。

出于性能考虑,将jquery查询分为2是很重要的,因为jquery从右向左读取它们,代码如下:

$("select[readonly] option:not(:selected)")

将首先找到文档中所有未选中的选项,然后筛选那些在具有只读属性的选择内的选项。