【问题标题】:How do I get tailwinds active breakpoint in JavaScript?如何在 JavaScript 中获得顺风活动断点?
【发布时间】:2020-05-15 19:58:20
【问题描述】:

我正在使用配置文件构建顺风并将其包含在反应项目中。

我想在 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 中获得相同的效果?

【问题讨论】:

    标签: javascript css reactjs tailwind-css


    【解决方案1】:

    从 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

    【讨论】:

    • 如果我使用的是 react 项目,我无法从 './tailwind.config.js' 导入 tailwindConfig 是否有替代方案?
    【解决方案2】:

    这是我在Typescript 中写的,它根据设备宽度返回当前断点。您可以将它放在一个独立的文件中,并在需要时在任何文件中导入方法:

    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;
    

    【讨论】:

    • 感谢您的 sn-p。它不能正常工作,因为getBreakpointValue 正在返回一个字符串,而&gt;= 字符串和数字之间的比较使事情变得很奇怪。我用const getBreakpointValue = (value: string): number =&gt; parseInt(fullConfig.theme.screens[value].replace('px', ''), 10);解决了它
    • 遗憾的是,在 Angular 中这不起作用。无法以角度访问 css 变量,这非常令人沮丧。
    【解决方案3】:

    如果有人正在寻找不使用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>
    

    然后,您可以编写一个函数来查找这些元素并通过每个元素的 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 的实际断点系统来确定当前处于活动状态的断点。

    【讨论】:

      【解决方案4】:

      对于那些使用 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>
        );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-30
        • 2021-06-02
        • 2020-11-12
        • 2017-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多