Pra*_*h S 2 javascript css reactjs tailwind-css
我正在使用配置文件构建顺风并将其包含在反应项目中。
我想在 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>Run Code Online (Sandbox Code Playgroud)
上面显示了活动断点。但是如何在不包含上述任何标记的情况下在 js 中获得相同的结果。?
ana*_*nar 17
对于那些使用 TypeScript 4.5+ 的人来说,这是一个小钩子。它基于包装useMediaQuery中的挂钩react-responsive。随意修改吧!
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>;
}
Run Code Online (Sandbox Code Playgroud)
在你的组件内部,像这样使用它
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>
);
Run Code Online (Sandbox Code Playgroud)
roz*_*058 13
从 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)'
Run Code Online (Sandbox Code Playgroud)
正如您在上面看到的,您可以通过引用fullConfig.theme.screens.{breakpoint}. 您应该能够使用 javascript 将其与您当前的屏幕宽度进行比较。
pa4*_*080 12
我结合了其他解决方案来实现我所需要的。
/**
* @desc The 'useBreakpoint()' hook is used to get the current
* screen breakpoint based on the TailwindCSS config.
*
* @usage
* import { useBreakpoint } from "@/hooks/useBreakpoint";
*
* const { isAboveSm, isBelowSm, sm } = useBreakpoint("sm");
* console.log({ isAboveSm, isBelowSm, sm });
*
* const { isAboveMd } = useBreakpoint("md");
* const { isAboveLg } = useBreakpoint("lg");
* const { isAbove2Xl } = useBreakpoint("2xl");
* console.log({ isAboveMd, isAboveLg, isAbove2Xl });
*
* @see https://stackoverflow.com/a/76630444/6543935
* @requirements npm install react-responsive
*/
import { useMediaQuery } from "react-responsive";
import resolveConfig from "tailwindcss/resolveConfig";
import { Config, ScreensConfig } from "tailwindcss/types/config";
import tailwindConfig from "@/tailwind.config"; // Your tailwind config
const fullConfig = resolveConfig(tailwindConfig as unknown as Config);
const breakpoints = fullConfig?.theme?.screens || {
xs: "480px",
sm: "640px",
md: "768px",
lg: "1024px",
xl: "1280px",
};
export function useBreakpoint<K extends string>(breakpointKey: K) {
const breakpointValue = breakpoints[breakpointKey as keyof typeof breakpoints];
const bool = useMediaQuery({
query: `(max-width: ${breakpointValue})`,
});
const capitalizedKey = breakpointKey[0].toUpperCase() + breakpointKey.substring(1);
type KeyAbove = `isAbove${Capitalize<K>}`;
type KeyBelow = `isBelow${Capitalize<K>}`;
return {
[breakpointKey]: Number(String(breakpointValue).replace(/[^0-9]/g, "")),
[`isAbove${capitalizedKey}`]: !bool,
[`isBelow${capitalizedKey}`]: bool,
} as Record<K, number> & Record<KeyAbove | KeyBelow, boolean>;
}
Run Code Online (Sandbox Code Playgroud)
以下是 Next.js 13 中与应用程序路由器一起使用的示例:
"use client";
import React, { useEffect } from "react";
import { useBreakpoint } from "@/hooks/useBreakpoint";
const Nav: React.FC = () => {
const { isAboveSm, isBelowSm, sm } = useBreakpoint("sm");
useEffect(() => {
console.log({ isAboveSm, isBelowSm, sm });
});
return (
<> ... </>
);
};
Run Code Online (Sandbox Code Playgroud)
控制台输出(屏幕宽度大于 640px):
{ isAboveSm: true, isBelowSm: false, sm: 640 }
Run Code Online (Sandbox Code Playgroud)
如果 Next.js 抱怨服务器端渲染与客户端不匹配,您可以使用useLayoutEffect()钩子:
{ isAboveSm: true, isBelowSm: false, sm: 640 }
Run Code Online (Sandbox Code Playgroud)
注意:根据您的配置,您可能需要将文件更改tailwind.config为module.exports = {...}:
const [isBwXs, setIsBwXs] = React.useState<boolean>(false);
const { isBelowXs } = useBreakpoint("xs");
useLayoutEffect(() => {
setIsBwXs(isBelowXs);
}, [isBelowXs]);
Run Code Online (Sandbox Code Playgroud)
这是我写的Typescript根据设备宽度返回当前断点的内容。你可以把它放在一个独立的文件中,并在任何需要的时候导入任何文件中的方法:
import resolveConfig from 'tailwindcss/resolveConfig';
import tailwindConfig from './tailwind.config.js'; // 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;
};
Run Code Online (Sandbox Code Playgroud)
如果有人正在寻找一种不使用 tailwind 配置的方法,您可以通过使用 tailwind 的断点系统来控制多个 0x0 div 的可见性,并测试这些 div 的可见性以确定当前活动断点来实现此目的。
例如,您可以在正文中嵌入多个大小为 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>
Run Code Online (Sandbox Code Playgroud)
然后,您可以编写一个函数来查找这些元素并通过每个元素的 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;
};
Run Code Online (Sandbox Code Playgroud)
现在您可以测试当前断点字符串以执行一些逻辑:
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)
}
Run Code Online (Sandbox Code Playgroud)
您需要确保 Tailwind 使用的任何断点都应用于您可以获得的文档中某处的 0x0 div,并检查 getCurrentBreakpoint() 函数中的这些断点。但这无需检查 Tailwind 的配置即可完成工作,并使用 Tailwind 的实际断点系统来确定哪个当前处于活动状态。