如何在 JavaScript 中获得顺风活动断点?

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)

  • 如果您的 tailwind 配置不完整并且仅扩展了默认配置,您需要使用以下命令解析完整的配置: `import resolveConfig from "tailwindcss/resolveConfig"; 从“../../tailwind.config”导入 tailwindConfig;const fullConfig = resolveConfig(tailwindConfig);` 并访问断点:`const Breakpoints = fullConfig.theme.screens;` (6认同)

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 将其与您当前的屏幕宽度进行比较。

在此处查看更多信息

  • 如果我使用的是 React 项目,我无法从“./tailwind.config.js”导入 tailwindConfig,还有其他选择吗? (2认同)
  • @S_coderX451 React 与能够从 tailwind.config.js 导入无关,如果您在项目目录的根目录下运行了 `npx tailwindcss init` ,您将拥有一个 tailwind.config.js 文件。您必须确保路径“../../tailwind.config.js”正确。如果您要导入文件 x.js,并且 x.js 位于 {projectRoot}/components/x.js 中。导入将是“import tailwindConfig from '../tailwind.config.js'”。 (2认同)

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.configmodule.exports = {...}

const [isBwXs, setIsBwXs] = React.useState<boolean>(false);
const { isBelowXs } = useBreakpoint("xs");

useLayoutEffect(() => {
    setIsBwXs(isBelowXs);
}, [isBelowXs]);
Run Code Online (Sandbox Code Playgroud)


Sin*_*dro 5

这是我写的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)

  • 谢谢你的片段。它无法正常工作,因为 `getBreakpointValue` 返回一个字符串,而字符串和数字之间的 `&gt;=` 比较造成了奇怪的事情。我用 const getBreakpointValue = (value: string): number =&gt; parseInt(fullConfig.theme.screens[value].replace('px', ''), 10);` 解决了这个问题 (2认同)

Ada*_*eld 5

如果有人正在寻找一种不使用 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 的实际断点系统来确定哪个当前处于活动状态。