如何优化Bootstrap4下拉排序jQuery代码 避免if判断地狱
Bootstrap4下拉排序功能优化方案
你的代码之所以出现if地狱,本质是把选项配置和交互逻辑写死在了分支判断里,用配置映射或者data属性传值的方式可以完全消除嵌套判断,同时代码可维护性会高很多。
优化思路
- 把重复的「同组选项移除active、当前项加active」的逻辑抽成通用操作,不用每个分支写一遍
- 把每个选项对应的查询参数、显示文本和逻辑解耦:要么提前存在配置映射表里,要么直接写在HTML的自定义属性上,不用靠id数值范围判断选项类型
- 替换语义模糊的变量名,降低后续维护的理解成本
方案1:配置映射表版(不用改原有HTML结构)
直接替换原有JS代码即可,原有HTML不用动:
// 初始化默认排序值 let sortField = 'id'; let sortFieldText = 'ID'; let sortOrder = 'asc'; let sortOrderText = 'ASC'; // 选项配置映射表,后续新增排序选项直接在这里加配置即可,不需要修改点击逻辑 const sortMap = { 1: { group: 'cat', query: 'id', text: 'ID' }, 2: { group: 'cat', query: 'title', text: 'Title' }, 3: { group: 'cat', query: 'created_at', text: 'Date added' }, 4: { group: 'cat', query: 'updated_at', text: 'Date edited' }, 5: { group: 'order', query: 'asc', text: 'ASC' }, 6: { group: 'order', query: 'desc', text: 'DESC' } } // 初始化排序提示文本 $('#sort_text').html(`${sortFieldText}•${sortOrderText}`); $('#ul_sort a').click(function(e) { e.stopPropagation(); const $currentItem = $(this); const itemId = $currentItem.attr('id'); const itemConfig = sortMap[itemId]; if (!itemConfig) return; // 统一处理同组active状态切换 const groupClass = itemConfig.group === 'cat' ? '.sort_cat' : '.sort_order'; $(groupClass).removeClass('active'); $currentItem.addClass('active'); // 更新对应分组的排序值 if (itemConfig.group === 'cat') { sortField = itemConfig.query; sortFieldText = itemConfig.text; } else { sortOrder = itemConfig.query; sortOrderText = itemConfig.text; } // 刷新提示文本,需要传给后端的排序参数直接用sortField和sortOrder拼接即可 $('#sort_text').html(`${sortFieldText}•${sortOrderText}`); });
方案2:data属性版(长期维护更方便)
如果后续会频繁调整排序选项,推荐把配置直接写在HTML元素上,连映射表都不用维护,新增选项只需要写HTML即可:
调整后的HTML选项部分
<ul id="ul_sort" class="dropdown-menu text-decoration-none"> <a class="sort_cat dropdown-item active" data-query="id" data-text="ID">ID</a> <a class="sort_cat dropdown-item" data-query="title" data-text="Title">Title</a> <a class="sort_cat dropdown-item" data-query="created_at" data-text="Date added">Date added</a> <a class="sort_cat dropdown-item" data-query="updated_at" data-text="Date edited">Date edited</a> <li class="dropdown-divider"></li> <a class="sort_order dropdown-item px-3 active" data-query="asc" data-text="ASC"> Ascending <span class="float-right bi bi-arrow-up-short"></span> </a> <a class="sort_order dropdown-item px-3" data-query="desc" data-text="DESC"> Descending <span class="float-right bi bi-arrow-down-short"></span> </a> </ul>
对应简化后的JS
// 初始化默认值 let sortFieldText = 'ID', sortOrderText = 'ASC'; $('#sort_text').html(`${sortFieldText}•${sortOrderText}`); $('#ul_sort a').click(function(e) { e.stopPropagation(); const $current = $(this); const isSortCat = $current.hasClass('sort_cat'); const groupClass = isSortCat ? '.sort_cat' : '.sort_order'; // 切换同组active状态 $current.addClass('active').siblings(groupClass).removeClass('active'); // 更新对应分组文本 if (isSortCat) { sortFieldText = $current.data('text'); // 后端需要的排序字段直接取 $current.data('query') } else { sortOrderText = $current.data('text'); // 后端需要的排序规则直接取 $current.data('query') } $('#sort_text').html(`${sortFieldText}•${sortOrderText}`); });
优化收益
- 完全消除多层嵌套if,代码行数减少40%以上,逻辑一目了然
- 选项和逻辑解耦,新增/修改排序选项不需要调整核心交互代码,不会因为加分支写出新的bug
- 替换了原来语义模糊的
for_button_text_1/2变量名,后续看代码不用再回忆两个变量分别对应什么 - 避免了原代码中id取出来是字符串、和数字做
==比较带来的隐式类型转换隐患
内容的提问来源于stack exchange,提问作者deacon leid
相关产品推荐
相关产品推荐

