如何正确指定函数禁用条件?WordPress多模块交互问题
问题
现有多个(当前展示2个).variation模块,每个模块包含1个checkbox、2个select组件,以及需根据select选项进行显隐的.date元素。
需求:当勾选某模块内的checkbox时,该模块中的其中一个select停止控制.date元素的显隐;未勾选时恢复对应控制逻辑。
目前,select控制.date显隐的功能已正常实现,但无法正确设置基于checkbox状态的函数禁用条件,且因使用WordPress无法修改现有HTML结构。请帮忙完善代码中的if条件逻辑,实现上述需求。
现有代码
JavaScript
$(document).on('change', 'input.checkbox', function (evt) { const variation = evt.target.closest('.variation'); const checkbox = evt.target; const on = checkbox.matches('input.checkbox:checked') && 'on' === checkbox.value; if ((variation && on) == true){ // If the checkbox is enabled console.log('On'); $(document).on('change', '.show select', function (evt) { const variation = evt.target.closest('.variation'); const select = evt.target; const showDate = select.matches('[name*="vb"]') && ['notify', 'yes'].includes(select.value); variation.querySelector('.date').classList.toggle('visible', showDate); }); } else { // If the checkbox is not enabled console.log('Off'); $(document).on('change', '.vss select', function (evt) { const variation = evt.target.closest('.variation'); const select = evt.target; const showDate = select.matches('[name*="vss"]') && 'onbackorder' === select.value; variation.querySelector('.date').classList.toggle('visible', showDate); }); } });
CSS
.variations { padding: 20px; background-color: #ededed; font-size: 20px; } .variation { padding: 20px; background-color: #e3e3e3; } .variation:first-child { background-color: #f5f5f5; } .date { display: none; } .date.visible { display: block; }
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="variations"> <div class="variation"><b>First variation</b> <input type="checkbox" class="checkbox" name="vms[0]"> <div class="show"> select 1 <select style="" id="backorders0" name="vb[0]"> <option value="no">Do not allow</option> <option value="notify">Allow but notify client</option> <option value="yes" selected>Allow</option> </select> </div> <div> <p class="vss"> select 2 <select style="" id="vss0" name="vss[0]"> <option value="instock" >In stock</option> <option value="outofstock">Out of stock</option> <option value="onbackorder" selected >Pre-order</option> </select> </p> <p class="date"><input value="It needs to be hidden/showed"></p> </div> </div> <div class="variation"><b>Second variation</b> <input type="checkbox" class="checkbox" name="vms[1]"> <div class="show"> select 1 <select style="" id="backorders1" name="vb[1]"> <option value="no" selected>Do not allow</option> <option value="notify">Allow but notify client</option> <option value="yes" >Allow</option> </select> </div> <div> <p class="vss"> select 2 <select style="" id="vss1" name="vss[1]"> <option value="instock" >In stock</option> <option value="outofstock" selected>Out of stock</option> <option value="onbackorder" >Pre-order</option> </select> </p> <p class="date"><input value="It needs to be hidden/showed"></p> </div> </div> </div>
解决方案
原代码的核心问题是重复绑定事件(每次checkbox切换都会新增select事件监听,导致多次触发),且未针对单个模块隔离状态判断。以下是修正后的代码及逻辑说明:
修正后的JavaScript代码
// 一次性绑定所有目标select的change事件,避免重复绑定 $(document).on('change', '.show select, .vss select', function (evt) { const select = evt.target; const variation = select.closest('.variation'); const checkbox = variation.querySelector('.checkbox'); const isChecked = checkbox.checked; const dateElement = variation.querySelector('.date'); // 根据select类型和checkbox状态执行对应逻辑 if (select.matches('[name*="vb"]')) { // 仅当checkbox未勾选时,才让该select控制.date显隐 if (!isChecked) { const showDate = ['notify', 'yes'].includes(select.value); dateElement.classList.toggle('visible', showDate); } } else if (select.matches('[name*="vss"]')) { // 该select始终按原逻辑控制显隐(若需勾选时停止,添加!isChecked判断即可) const showDate = 'onbackorder' === select.value; dateElement.classList.toggle('visible', showDate); } }); // 页面初始化时,根据初始状态设置.date的显隐 $('.variation').each(function() { const variation = this; const checkbox = variation.querySelector('.checkbox'); const vbSelect = variation.querySelector('[name*="vb"]'); const vssSelect = variation.querySelector('[name*="vss"]'); const dateElement = variation.querySelector('.date'); let showDate = false; // 初始状态:未勾选checkbox时,同时考虑两个select的取值;勾选时仅考虑vss的取值 if (!checkbox.checked) { showDate = ['notify', 'yes'].includes(vbSelect.value) || 'onbackorder' === vssSelect.value; } else { showDate = 'onbackorder' === vssSelect.value; } dateElement.classList.toggle('visible', showDate); });
逻辑说明
- 事件绑定优化:不再在checkbox切换时重复绑定select事件,而是一次性绑定所有目标select的change事件,避免事件叠加触发导致的逻辑混乱。
- 模块隔离控制:每个select触发事件时,仅获取当前所属
.variation模块的checkbox状态,确保不同模块的控制逻辑互不干扰。 - 状态判断逻辑:
- 对于
.show下的select(name含vb):仅当模块内checkbox未勾选时,才根据其选项控制.date的显隐;勾选时跳过该控制逻辑,实现“停止控制”的需求。 - 对于
.vss下的select(name含vss):保持原逻辑始终生效(若需要勾选时该select也停止控制,只需在其逻辑前添加if(!isChecked)判断即可)。
- 对于
- 初始化处理:页面加载完成后,自动根据checkbox的初始状态和select的默认值设置
.date的显隐状态,确保初始显示符合预期。
内容的提问来源于stack exchange,提问作者Yuriy
相关产品推荐
相关产品推荐

