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

Posted

技术标签:

【中文标题】如何在 JavaScript 中获得顺风活动断点?【英文标题】:How do I get tailwinds active breakpoint in 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 中获得相同的效果?

【问题讨论】:

【参考方案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>
  );

【讨论】:

以上是关于如何在 JavaScript 中获得顺风活动断点?的主要内容,如果未能解决你的问题,请参考以下文章

如何删除:活动状态下的多余边框?顺风

如何在 chrome 中的内联 javascript 中添加断点

如何在 Google Chrome 的内联 Javascript 中设置断点?

在 Chrome 中单步执行 JavaScript 断点时如何查看 DOM?

配置中的 Tailwind 新屏幕添加导致默认断点不起作用

如果未选中,则对单选按钮进行自定义验证 |顺风