如何在 JavaScript 中获取 tailwinds 活动断点?
How do I get tailwinds active breakpoint in JavaScript?
我正在使用配置文件构建 tailwind 并将其包含在 React 项目中。
我想获取 javascript/React 中的活动断点值。我怎样才能达到同样的效果?
<div class="block sm:hidden md:hidden lg:hidden xl:hidden">al</div>
<div class="hidden sm:block md:hidden lg:hidden xl:hidden">sm</div>
<div class="hidden sm:hidden md:block lg:hidden xl:hidden">md</div>
<div class="hidden sm:hidden md:hidden lg:block xl:hidden">lg</div>
<div class="hidden sm:hidden md:hidden lg:hidden xl:block">xl</div>
</div>
上面显示的是活动断点。但是我如何在不包含上述任何标记的情况下在 js 中获得相同的结果?
从 tailwind 文档中,您可以从 tailwindcss
节点模块导入您的配置:
import resolveConfig from 'tailwindcss/resolveConfig'
import tailwindConfig from './tailwind.config.js'
const fullConfig = resolveConfig(tailwindConfig)
fullConfig.theme.width[4]
// => '1rem'
fullConfig.theme.screens.md
// => '768px'
fullConfig.theme.boxShadow['2xl']
// => '0 25px 50px -12px rgba(0, 0, 0, 0.25)'
正如你在上面看到的,你可以通过引用fullConfig.theme.screens.{breakpoint}
来获取你的断点。您应该能够使用 javascript.
将其与您当前的屏幕宽度进行比较
查看更多here.
这是我在Typescript
中写的returns当前断点基于设备宽度。您可以将它放在一个独立的文件中,并在需要时在任何文件中导入方法:
import resolveConfig from 'tailwindcss/resolveConfig';
import tailwindConfig from './tailwind.config'; // Fix the path
const fullConfig = resolveConfig(tailwindConfig);
export const getBreakpointValue = (value: string): number =>
+fullConfig.theme.screens[value].slice(
0,
fullConfig.theme.screens[value].indexOf('px')
);
export const getCurrentBreakpoint = (): string => {
let currentBreakpoint: string;
let biggestBreakpointValue = 0;
for (const breakpoint of Object.keys(fullConfig.theme.screens)) {
const breakpointValue = getBreakpointValue(breakpoint);
if (
breakpointValue > biggestBreakpointValue &&
window.innerWidth >= breakpointValue
) {
biggestBreakpointValue = breakpointValue;
currentBreakpoint = breakpoint;
}
}
return currentBreakpoint;
};
编辑:
在较新的 Typescript 版本中,您必须将这两个参数添加到 compilerOptions
下的 tsconfig.json
才能导入 js 文件:
"compilerOptions": {
"allowJs": true,
"allowsyntheticdefaultimports": true
}
此外,如果您在 Angular 上并收到 process
未定义的错误,您必须将这些行添加到 polyfills.ts
文件的末尾(您有当然要安装 process
包):
import * as process from 'process';
window['process'] = process;
如果有人正在寻找不使用 tailwind 的配置的方法,您可以通过使用 tailwind 的断点系统来控制几个 0x0 div 的可见性并测试它们的可见性来实现这一点divs 确定当前活动断点。
例如,您可以像这样在体内嵌入几个大小为 0 的 div:
<div id="breakpoint-sm" class="hidden sm:block md:hidden lg:hidden xl:hidden 2xl:hidden w-0 h-0"></div>
<div id="breakpoint-md" class="hidden sm:hidden md:block lg:hidden xl:hidden 2xl:hidden w-0 h-0"></div>
<div id="breakpoint-lg" class="hidden sm:hidden md:hidden lg:block xl:hidden 2xl:hidden w-0 h-0"></div>
<div id="breakpoint-xl" class="hidden sm:hidden md:hidden lg:hidden xl:block 2xl:hidden w-0 h-0"></div>
<div id="breakpoint-2xl" class="hidden sm:hidden md:hidden lg:hidden xl:hidden 2xl:block w-0 h-0"></div>
然后,您可以编写一个函数来查找这些元素并通过每个元素的 offsetParent 检查它们是否可见 属性:
const getCurrentBreakpoint = (): string => {
const breakpointUnknown: string = 'unknown';
const breakpointSM: string | null = document.getElementById('breakpoint-sm')?.offsetParent === null ? null : 'sm';
const breakpointMD: string | null = document.getElementById('breakpoint-md')?.offsetParent === null ? null : 'md';
const breakpointLG: string | null = document.getElementById('breakpoint-lg')?.offsetParent === null ? null : 'lg';
const breakpointXL: string | null = document.getElementById('breakpoint-xl')?.offsetParent === null ? null : 'xl';
const breakpoint2XL: string | null = document.getElementById('breakpoint-2xl')?.offsetParent === null ? null : '2xl';
const breakpoint = breakpointSM ?? breakpointMD ?? breakpointLG ?? breakpointXL ?? breakpoint2XL ?? breakpointUnknown;
return breakpoint;
};
现在您可以测试当前断点字符串以执行一些逻辑:
const breakpoint = getCurrentBreakpoint();
const desktopBreakpoints: string[] = ['sm', 'md', 'lg', 'xl'];
if (desktopBreakpoints.includes(breakpoint)) {
// On Desktop (in Tailwind's eyes)
} else {
// On Mobile (in Tailwind's eyes)
}
您需要确保 Tailwind 使用的任何断点都应用到文档中您可以获得的 0x0 div 某处,并在 getCurrentBreakpoint() 函数中检查这些断点。但这无需检查 Tailwind 的配置即可完成工作,并使用 Tailwind 的实际断点系统来确定哪个当前处于活动状态。
对于使用 TypeScript 4.5+ 的用户,这里有一个小钩子。它基于 react-responsive
包中的 useMediaQuery
钩子。随意修改!
import { useMediaQuery } from 'react-responsive';
import { theme } from '../../tailwind.config'; // Your tailwind config
const breakpoints = theme.screens;
type BreakpointKey = keyof typeof breakpoints;
export function useBreakpoint<K extends BreakpointKey>(breakpointKey: K) {
const bool = useMediaQuery({
query: `(min-width: ${breakpoints[breakpointKey]})`,
});
const capitalizedKey = breakpointKey[0].toUpperCase() + breakpointKey.substring(1);
type Key = `is${Capitalize<K>}`;
return {
[`is${capitalizedKey}`]: bool,
} as Record<Key, boolean>;
}
在你的组件中,像这样使用它
const { isSm } = useBreakpoint('sm');
const { isMd } = useBreakpoint('md');
const { isLg } = useBreakpoint('lg');
return (
<div>
{isSm && (
{/* Visible for sm: (min-width: 640px) */}
<div>Content</div>
)}
{isMd && (
{/* Visible for md: (min-width: 768px) */}
<div>Content</div>
)}
</div>
);
为此,我使用了这段代码:
import { theme } from '../../tailwind.config';
export function getCurrentBreakpoints() {
return Object.keys(theme.screens).find((key) => window.innerWidth > theme.screens[key]);
}
我正在使用配置文件构建 tailwind 并将其包含在 React 项目中。
我想获取 javascript/React 中的活动断点值。我怎样才能达到同样的效果?
<div class="block sm:hidden md:hidden lg:hidden xl:hidden">al</div>
<div class="hidden sm:block md:hidden lg:hidden xl:hidden">sm</div>
<div class="hidden sm:hidden md:block lg:hidden xl:hidden">md</div>
<div class="hidden sm:hidden md:hidden lg:block xl:hidden">lg</div>
<div class="hidden sm:hidden md:hidden lg:hidden xl:block">xl</div>
</div>
上面显示的是活动断点。但是我如何在不包含上述任何标记的情况下在 js 中获得相同的结果?
从 tailwind 文档中,您可以从 tailwindcss
节点模块导入您的配置:
import resolveConfig from 'tailwindcss/resolveConfig'
import tailwindConfig from './tailwind.config.js'
const fullConfig = resolveConfig(tailwindConfig)
fullConfig.theme.width[4]
// => '1rem'
fullConfig.theme.screens.md
// => '768px'
fullConfig.theme.boxShadow['2xl']
// => '0 25px 50px -12px rgba(0, 0, 0, 0.25)'
正如你在上面看到的,你可以通过引用fullConfig.theme.screens.{breakpoint}
来获取你的断点。您应该能够使用 javascript.
查看更多here.
这是我在Typescript
中写的returns当前断点基于设备宽度。您可以将它放在一个独立的文件中,并在需要时在任何文件中导入方法:
import resolveConfig from 'tailwindcss/resolveConfig';
import tailwindConfig from './tailwind.config'; // Fix the path
const fullConfig = resolveConfig(tailwindConfig);
export const getBreakpointValue = (value: string): number =>
+fullConfig.theme.screens[value].slice(
0,
fullConfig.theme.screens[value].indexOf('px')
);
export const getCurrentBreakpoint = (): string => {
let currentBreakpoint: string;
let biggestBreakpointValue = 0;
for (const breakpoint of Object.keys(fullConfig.theme.screens)) {
const breakpointValue = getBreakpointValue(breakpoint);
if (
breakpointValue > biggestBreakpointValue &&
window.innerWidth >= breakpointValue
) {
biggestBreakpointValue = breakpointValue;
currentBreakpoint = breakpoint;
}
}
return currentBreakpoint;
};
编辑:
在较新的 Typescript 版本中,您必须将这两个参数添加到 compilerOptions
下的 tsconfig.json
才能导入 js 文件:
"compilerOptions": {
"allowJs": true,
"allowsyntheticdefaultimports": true
}
此外,如果您在 Angular 上并收到 process
未定义的错误,您必须将这些行添加到 polyfills.ts
文件的末尾(您有当然要安装 process
包):
import * as process from 'process';
window['process'] = process;
如果有人正在寻找不使用 tailwind 的配置的方法,您可以通过使用 tailwind 的断点系统来控制几个 0x0 div 的可见性并测试它们的可见性来实现这一点divs 确定当前活动断点。
例如,您可以像这样在体内嵌入几个大小为 0 的 div:
<div id="breakpoint-sm" class="hidden sm:block md:hidden lg:hidden xl:hidden 2xl:hidden w-0 h-0"></div>
<div id="breakpoint-md" class="hidden sm:hidden md:block lg:hidden xl:hidden 2xl:hidden w-0 h-0"></div>
<div id="breakpoint-lg" class="hidden sm:hidden md:hidden lg:block xl:hidden 2xl:hidden w-0 h-0"></div>
<div id="breakpoint-xl" class="hidden sm:hidden md:hidden lg:hidden xl:block 2xl:hidden w-0 h-0"></div>
<div id="breakpoint-2xl" class="hidden sm:hidden md:hidden lg:hidden xl:hidden 2xl:block w-0 h-0"></div>
然后,您可以编写一个函数来查找这些元素并通过每个元素的 offsetParent 检查它们是否可见 属性:
const getCurrentBreakpoint = (): string => {
const breakpointUnknown: string = 'unknown';
const breakpointSM: string | null = document.getElementById('breakpoint-sm')?.offsetParent === null ? null : 'sm';
const breakpointMD: string | null = document.getElementById('breakpoint-md')?.offsetParent === null ? null : 'md';
const breakpointLG: string | null = document.getElementById('breakpoint-lg')?.offsetParent === null ? null : 'lg';
const breakpointXL: string | null = document.getElementById('breakpoint-xl')?.offsetParent === null ? null : 'xl';
const breakpoint2XL: string | null = document.getElementById('breakpoint-2xl')?.offsetParent === null ? null : '2xl';
const breakpoint = breakpointSM ?? breakpointMD ?? breakpointLG ?? breakpointXL ?? breakpoint2XL ?? breakpointUnknown;
return breakpoint;
};
现在您可以测试当前断点字符串以执行一些逻辑:
const breakpoint = getCurrentBreakpoint();
const desktopBreakpoints: string[] = ['sm', 'md', 'lg', 'xl'];
if (desktopBreakpoints.includes(breakpoint)) {
// On Desktop (in Tailwind's eyes)
} else {
// On Mobile (in Tailwind's eyes)
}
您需要确保 Tailwind 使用的任何断点都应用到文档中您可以获得的 0x0 div 某处,并在 getCurrentBreakpoint() 函数中检查这些断点。但这无需检查 Tailwind 的配置即可完成工作,并使用 Tailwind 的实际断点系统来确定哪个当前处于活动状态。
对于使用 TypeScript 4.5+ 的用户,这里有一个小钩子。它基于 react-responsive
包中的 useMediaQuery
钩子。随意修改!
import { useMediaQuery } from 'react-responsive';
import { theme } from '../../tailwind.config'; // Your tailwind config
const breakpoints = theme.screens;
type BreakpointKey = keyof typeof breakpoints;
export function useBreakpoint<K extends BreakpointKey>(breakpointKey: K) {
const bool = useMediaQuery({
query: `(min-width: ${breakpoints[breakpointKey]})`,
});
const capitalizedKey = breakpointKey[0].toUpperCase() + breakpointKey.substring(1);
type Key = `is${Capitalize<K>}`;
return {
[`is${capitalizedKey}`]: bool,
} as Record<Key, boolean>;
}
在你的组件中,像这样使用它
const { isSm } = useBreakpoint('sm');
const { isMd } = useBreakpoint('md');
const { isLg } = useBreakpoint('lg');
return (
<div>
{isSm && (
{/* Visible for sm: (min-width: 640px) */}
<div>Content</div>
)}
{isMd && (
{/* Visible for md: (min-width: 768px) */}
<div>Content</div>
)}
</div>
);
为此,我使用了这段代码:
import { theme } from '../../tailwind.config';
export function getCurrentBreakpoints() {
return Object.keys(theme.screens).find((key) => window.innerWidth > theme.screens[key]);
}