能否自定义jQuery默认选择器,适配postcss-modules生成的带前后缀类名?
解决方案
实现思路
- 先保留jQuery所有原始方法的引用,避免原生功能丢失
- 封装通用工具函数:分别处理选择器字符串、多类名字符串,仅对类名部分做转换,id、标签、属性选择器逻辑保持不变
- 重写jQuery核心入口
$和所有涉及类名操作的原型方法,对传入参数做前置转换后再调用原生逻辑
完整实现代码
// 替换为你自己已封装的类名转换函数即可,输入原始类名(不带点)返回转换后的类名(不带点) const className = (rawClass) => { return `ABC_${rawClass}_XYZ` } // 工具函数:转换选择器中的类名片段,自动跳过id、标签、属性选择器内的点符号 const transformSelector = (selector) => { if (typeof selector !== 'string') return selector // 匹配不在[]、引号包裹范围内的 .类名 片段 return selector.replace(/(^|\s|\W)\.([a-zA-Z0-9_-]+)/g, (match, prefix, rawClass) => { return `${prefix}.${className(rawClass)}` }) } // 工具函数:转换空格分隔的多类名字符串 const transformClassList = (classStr) => { if (typeof classStr !== 'string') return classStr return classStr.split(/\s+/).map(raw => className(raw)).join(' ') } // 1. 重写jQuery核心选择器入口$ const originalJQuery = window.$ window.$ = function (selector, context) { if (typeof selector === 'string') { selector = transformSelector(selector) } return originalJQuery(selector, context) } // 继承jQuery原有静态属性和方法,避免其他依赖报错 Object.assign(window.$, originalJQuery) // 2. 重写jQuery原型上的类相关方法 const originalMethods = { addClass: $.fn.addClass, removeClass: $.fn.removeClass, hasClass: $.fn.hasClass, closest: $.fn.closest, find: $.fn.find, filter: $.fn.filter, parents: $.fn.parents, parent: $.fn.parent, siblings: $.fn.siblings, next: $.fn.next, prev: $.fn.prev } // 批量重写接收选择器参数的遍历方法 $.fn.closest = $.fn.find = $.fn.filter = $.fn.parents = $.fn.parent = $.fn.siblings = $.fn.next = $.fn.prev = function (selector) { if (typeof selector === 'string') { selector = transformSelector(selector) } return originalMethods[this.nodeName.toLowerCase()].call(this, selector) } // 重写类名操作方法 $.fn.addClass = $.fn.removeClass = function (classNames) { classNames = transformClassList(classNames) return originalMethods[this.nodeName.toLowerCase()].call(this, classNames) } $.fn.hasClass = function (targetClass) { targetClass = transformClassList(targetClass) return originalMethods.hasClass.call(this, targetClass) }
效果验证
引入上述代码后,直接按照普通jQuery的写法传入原始类名即可,无需手动调用转换函数:
// 选择器查询 $(".some_class_name").show() $("div#test .container p").hide() // 类名操作 $(".btn").addClass("active") $(".card").removeClass("hidden") if ($(".submit").hasClass("disabled")) { // 业务逻辑 } // 遍历查询 const parentForm = $(".input").closest("form") const btnList = $(".card").find(".btn")
注意事项
- 正则默认覆盖绝大多数常规选择器场景,如果项目用到非常复杂的嵌套属性选择器,可以按需调整
transformSelector中的匹配规则 - 如果存在不需要转换的全局公共类名,可以在
className转换函数中增加白名单过滤逻辑
内容的提问来源于stack exchange,提问作者Thành Lã
相关产品推荐
相关产品推荐

