如何在JavaScript中对以媒体查询为键的对象按样式表顺序排序
媒体查询对象排序解决方案
实现逻辑
CSS 样式表的媒体查询遵循后写规则覆盖前写规则的特性,排序核心逻辑如下:
- 无媒体查询的
none项固定排在最前 - 所有
max-width类型的媒体查询排在min-width类型之前 - 同类型媒体查询按尺寸数值从小到大升序排列
代码实现
首先定义待排序的原始对象:
const mediaObj = { //none represent no media query none: "foo", '@media(max-width:450px)': "foo", '@media(min-width:1200px)': "foo", '@media(min-width:768px)': "foo", };
排序函数实现:
function sortMediaQueryObj(obj) { const entries = Object.entries(obj); entries.sort(([keyA], [keyB]) => { // none固定排最前 if (keyA === 'none') return -1; if (keyB === 'none') return 1; // 提取媒体查询的类型和尺寸数值 const getMediaInfo = (key) => { const matchRes = key.match(/@media\((max-width|min-width):(\d+)px\)/); return { type: matchRes[1], value: Number(matchRes[2]) } } const infoA = getMediaInfo(keyA); const infoB = getMediaInfo(keyB); // max-width全部排在min-width前面 if (infoA.type === 'max-width' && infoB.type === 'min-width') return -1; if (infoA.type === 'min-width' && infoB.type === 'max-width') return 1; // 同类型按数值升序排列 return infoA.value - infoB.value; }); // 重新构建对象,ES6+环境会保留键的插入顺序 return Object.fromEntries(entries); }
调用后得到的排序结果完全符合需求:
const sortedObj = sortMediaQueryObj(mediaObj); /* { none: "foo", '@media(max-width:450px)': "foo", '@media(min-width:768px)': "foo", '@media(min-width:1200px)': "foo" } */
注意事项
如果需要兼容ES6以下的老旧环境,建议使用Map结构存储排序后的结果,Map天生支持键的插入顺序保留,兼容性更稳定。
内容的提问来源于stack exchange,提问作者John Winston
相关产品推荐
相关产品推荐

