点击accessLevels父元素后如何立即将子input设为不可编辑?
问题分析与解决方案
问题描述
我有如下HTML表单:
<div class="party-group party-group_has-items" data-field-name="accessLevels">
点击该data-field-name为"accessLevels"的父元素时,会生成以下HTML结构:
<div class="form-group"> <label class="control-label control-label_main">Department</label> <div class="form-group-content"> <div class="form-field" data-editors="department"> <div class="form-field_type_string"> <span class="form-field__editor-wrapper"> <input type="text" class="form-field__editor form-field__editor_autosize"/> </span> </div> </div> </div> </div> </div>
我的需求是:点击accessLevels父元素时,将其下的input标签设为不可编辑,且仅对accessLevels区域生效。
目前我使用的解决方案如下:
$(document).on('click', 'div[data-field-name="accessLevels"] .form-field__editor', function() { $('div[data-field-name="accessLevels"] .form-field__editor').prop('readonly', true); });
但问题是,readonly的设置并非在点击父元素时立即生效,只有点击子input表单时才会生效,请问这是什么原因?
原因分析
你的事件绑定目标完全错了——当前代码把点击事件绑定到了accessLevels下的.form-field__editor(也就是那个input)上,只有点击这个input的时候才会触发readonly设置,根本没实现“点击父元素就生效”的需求。
另外还要注意:点击父元素后才会生成input元素,所以必须用事件委托绑定到父元素,还要确保在input生成完成后再设置属性。
修正后的解决方案
// 把点击事件绑定到data-field-name="accessLevels"的div上 $(document).on('click', 'div[data-field-name="accessLevels"]', function() { // 因为点击父元素生成input是异步操作,需要等DOM更新完成 // 如果知道生成input的回调函数,直接在回调里处理更靠谱,这里用定时器做兼容 setTimeout(() => { // 只操作当前点击的父元素下的input,避免影响其他同类型元素 $(this).find('.form-field__editor').prop('readonly', true); }, 100); });
补充说明
- 用
$(this).find()代替全局选择器,确保只对当前点击的accessLevels区域内的input生效,不会误操作页面其他同class的元素 - 定时器是为了兼容异步生成DOM的场景,如果能拿到生成input的回调钩子(比如组件的渲染完成事件),直接在钩子内执行设置逻辑会更精准,不需要依赖定时器延迟。
内容的提问来源于stack exchange,提问作者Vasek
相关产品推荐
相关产品推荐

