如何通过JavaScript获取由媒体查询定义的当前CSS值?

如何通过JavaScript获取由媒体查询定义的当前CSS值?,javascript,css,angular,Javascript,Css,Angular,我对这个问题的标题几乎与现有问题完全相同,但不幸的是,下面的答案不适用: 首先,我试图在使用特定类创建任何元素之前确定特定CSS类的值 其次,我希望获得样式表中所述的值,作为百分比,而不是像使用getComputedStyle那样重新计算为像素值 第三个复杂问题(是的,好像我需要更多!)是在特定角度组件的样式表中定义类,而不是在全局样式表中。我找不到document.styleSheets下列出的任何特定于角度组件的类 最重要的是,即使我将类移动到全局样式表,并查看document.style

我对这个问题的标题几乎与现有问题完全相同,但不幸的是,下面的答案不适用:

首先,我试图在使用特定类创建任何元素之前确定特定CSS类的值

其次,我希望获得样式表中所述的值,作为百分比,而不是像使用
getComputedStyle
那样重新计算为像素值

第三个复杂问题(是的,好像我需要更多!)是在特定角度组件的样式表中定义类,而不是在全局样式表中。我找不到
document.styleSheets
下列出的任何特定于角度组件的类

最重要的是,即使我将类移动到全局样式表,并查看
document.styleSheets
列出的所有
CSSStyleSheet
的所有
CSSStyleRules
,而我可以找到该特定类的规则,不幸的是,这些规则没有反映媒体查询动态做出的任何更改

以下是所涉及的特定CSS:

.my-class {
  display: flex;
  line-height: 1;
  min-width: 0;
  padding-bottom: 1em;
  padding-right: 1em;
}

@media all and (min-width: 0) {
  .my-class {
    width: 94%;
  }
}

@media all and (min-width: 768px) {
  .my-class {
    width: 47%;
  }
}

@media all and (min-width: 1024px) {
  .my-class {
    width: 31.5%;
  }
}

@media all and (min-width: 1366px) {
  .my-class {
    width: 23.5%;
  }
}

@media all and (min-width: 1700px) {
  .my-class {
    width: 19%;
  }
}

当我从浏览器窗口收到
调整大小
事件时,我想知道CSS和媒体查询选择的宽度(以百分比表示)。通过这种方式,我可以知道使用我的类可以水平显示多少项,然后在计算中使用该值来计算一个虚拟分页的项列表应该从服务器获取多少项

有一种解决方案我很确定可以使用,但并不理想:


通过JavaScript监控媒体查询的问题是,JavaScript代码必须与CSS中的任何更改手动同步,CSS中的每个断点都有一个单独的
matchMedia

我想到了两个选项

1(如你所说)

如果您想要一种动态方式,那么我建议您将该类的唯一元素隐藏在dom中的某个位置,然后根据当前值计算百分比

window.addEventListener('resize',()=>{
const contatinerWidth=document.getElementById('container').getBoundingClientRect().width;
const elmWidth=document.getElementById('elm').getBoundingClientRect().width;
常数百分比=宽度/连续宽度;
//此时,您知道css类应该给出的百分比是多少
console.log(百分比)
})
#容器{
位置:固定;
顶部:-300px;
/*所以没人能看到**/
宽度:100vw;
}
.测试{
宽度:50%;
}
@仅介质屏幕和(最大宽度:600px){
.测试{
宽度:70%;
}
}

就在@ehab发布他的解决方案之前,我想到了一些东西。两者都依赖于从CSS复制不同的媒体断点宽度(如果可能的话,我仍然希望避免),但ehab的解决方案比我原来的解决方案要好,因为它只使用一个窗口调整侦听器,而不是多个
MediaQueryList
侦听器

我修改了下面的解决方案,以考虑到他的更好想法,使用组件调整大小侦听器而不是窗口调整大小侦听器(),并添加一些去抖动和侦听器清理

  private columnCount = 1;
  private readonly screenWidths = [768, 1024, 1366, 1700];

  onResize = debounce(() => this.getColumnCount(), 100);

  private getColumnCount(): void {
    this.columnCount = 1;

    this.screenWidths.forEach((width, index) => {
      const mql = window.matchMedia(`all and (min-width: ${width}px)`);

      if (mql.matches) {
        this.columnCount = index + 2;
      }
    });

    console.log('column count:', this.columnCount);
  }

  ngOnInit(): void {
    addResizeListener(this.gridRef.nativeElement, this.onResize);
  }

  ngOnDestroy(): void {
    removeResizeListener(this.gridRef.nativeElement, this.onResize);
  }

如果你的全部目标是计算布局,为什么你不能检查一下调整大小的
窗口。innerWidth()?为什么你需要知道CSS告诉浏览器做什么,而不是它实际在做什么?因为其他人维护CSS,并且可能会改变他们关于多少项应该适合不同屏幕大小的想法。单个项目没有固定的宽度,因此,我不能将屏幕宽度除以特定的宽度,得到一个可靠匹配CSS所做操作的结果。我想我很困惑CSS中的断点是如何告诉浏览器执行与
元素不同的操作的选中的。。。这应该与CSS
相同。我的类{width:xx%;}
元素。innerWidth
不是固定大小,并且元素并不总是先存在,因此您甚至可以事先检查
元素。innerWidth
来进行分割。CSS决定将有多少列,这完全基于媒体查询中的特定断点。没有特定的公式用于计算这些断点和相关的百分比宽度,我可以基于JavaScript复制这些断点和百分比宽度,只查看
window.innerWidth
。有趣的是,你刚刚发布了这篇文章,因为我放弃了寻找比使用
mediaMatch
更好的东西。我为每个
MediaQueryList
都使用了一个侦听器,但是使用窗口调整事件的解决方案更干净(尽管我可能会对其进行去抖动处理,这样它就不会被频繁触发)。我会将我的解决方案作为一个单独的答案发布,只是为了比较(因为它太大了,无法发表评论),但我想我会在发布后修改我的解决方案,以便更接近您的解决方案。
  private columnCount = 1;
  private readonly screenWidths = [768, 1024, 1366, 1700];

  onResize = debounce(() => this.getColumnCount(), 100);

  private getColumnCount(): void {
    this.columnCount = 1;

    this.screenWidths.forEach((width, index) => {
      const mql = window.matchMedia(`all and (min-width: ${width}px)`);

      if (mql.matches) {
        this.columnCount = index + 2;
      }
    });

    console.log('column count:', this.columnCount);
  }

  ngOnInit(): void {
    addResizeListener(this.gridRef.nativeElement, this.onResize);
  }

  ngOnDestroy(): void {
    removeResizeListener(this.gridRef.nativeElement, this.onResize);
  }