【问题标题】:Javascript overriding CSS display property after change of media query媒体查询更改后 Javascript 覆盖 CSS 显示属性
【发布时间】:2018-02-13 17:05:11
【问题描述】:

我有一个表格,我需要在桌面上显示它并在移动设备上隐藏它,可以选择单击一个按钮来显示它,另一个按钮来隐藏它。它似乎工作正常,但是当我选择 Button2 以在桌面上的最小化视图中隐藏表格(模仿移动视图)并拖动浏览器以将其大小增加到桌面时,除非我刷新页面,否则表格将保持隐藏状态。

基本上,javascript 函数 close_table() 设置 display:none 覆盖 CSS display:block @min-width 481px

有没有办法确保在增加浏览器大小时(在选择按钮 2 之后)无需刷新即可看到表格?

任何提示/帮助将不胜感激。

下面是示例代码

HTML:

<button id="Button1" onclick="view_table()">View table</button>
<div id="table">
    <button id="Button2” onclick="close_table()">Hide table</button>
</div>

CSS:

@media (max-width:480px){
    #table {
        display: none;
    }
    #Button1 {
        display: block;
    }
}

@media (min-width:481px){
    #table {
        display: block;
    }
    #Button1 {
        display: none;
    }
}

JS:

function view_table() {
    document.getElementById("table").style.display="block"
}
function close_table() {
    document.getElementById("table").style.display="none"
}

【问题讨论】:

  • 脚本正在应用 inline 规则,这将超过任何外部或内部声明的 @media 规则 - 除非您将 !important 声明添加到相关的 @media 规则中。

标签: javascript css


【解决方案1】:

问题在于,当您说document.getElementById('table').styles.* 时,您是通过 DOM 直接设置元素的样式,其优先级高于通过 CSS 进行的媒体查询。这意味着当再次触发媒体查询时,不会发生任何事情,因为 DOM 元素现在具有更高优先级的样式,因此忽略 MQ 规则。

您也不能使用通常的 .hide .show 类,因为无法仅通过媒体查询添加或删除类。

剩下的 EventListeners 将监听正在调整大小的窗口并执行您想要的功能。

我找到了this article,并且能够使用它来编写代码 sn-p 来完成您正在寻找的功能。

JavaScript 可以访问 window.matchMedia,这是存储文档的所有媒体相关项目的地方。简而言之,这允许我们在 JavaScript 中直接使用类似媒体查询的字符串,而不仅仅是在我们的 CSS 中.

这里有一些关于媒体查询的附加资源,可能有助于您在学习时略读这些资源。

对于代码 sn-p,请单击整页以查看寡妇调整大小的样子。

Using Media Queries

Media Query types

MatchMedia()

/* Commented code on bottom is running. This is un-commented for easier readability.

'use strict'


if (matchMedia) { 
  const mq = window.matchMedia("(min-width: 481px)"); 
  mq.addListener(WidthChange); 
  WidthChange(mq); 
}

function WidthChange(mq) {
  if (mq.matches) {
    view_table() 
  } else {
    close_table()
  }
}

function view_table() {
  document.getElementById('table').style.visibility = 'visible'
  document.getElementById('button2').style.visibility = 'visible'
  document.getElementById('button1').style.visibility = 'hidden' 
}

function close_table() {
  document.getElementById('table').style.visibility = 'hidden'
  document.getElementById('button2').style.visibility = 'hidden'
  document.getElementById('button1').style.visibility = 'visible' 
}


*/

'use strict'


if (matchMedia) { // technically this is window.matchMedia, which is actually a function stored as a property on the window object. If the browser supports matchMedia then this is true. Else - no media queries regardless.

  const mq = window.matchMedia("(min-width: 481px)"); // The matchMedia() function is passed a media query string.

  mq.addListener(WidthChange);
  WidthChange(mq); // Immediately calls the new listener and pass in the mq object.
}

function WidthChange(mq) {
  // Equivalant to window.matchMedia("(min-width: 481px)").matches... .matches is a Boolean.
  if (mq.matches) {
    view_table() // If mq.matches is true ( meaning >= 481px)
  } else {
    close_table()
  }

}

function view_table() {
  document.getElementById('table').style.visibility = 'visible'
  document.getElementById('button2').style.visibility = 'visible'
  document.getElementById('button1').style.visibility = 'hidden' // You can also say display:none here on button1 to have the table move up into the spot where the button was for a cleaner look.
}

function close_table() {
  document.getElementById('table').style.visibility = 'hidden'
  document.getElementById('button2').style.visibility = 'hidden'
  document.getElementById('button1').style.visibility = 'visible' // If you do say display:none above, then this needs to beexactly what the original display property was.

}


// Note that this will update when the window go above or below the min-width.
// If you click the "view table" button  then make the window smaller
// it won't hide anything unless you went above the min-width then back down.
// This is because it's only triggered on a true or false change. If you want 
// it to be more reactive you can add more conditionals or check out MediaQueryList.change().
main {
  width: 100%;
}

table {
  width: 70%;
  border: 1px solid black;
  margin: auto;
}

.buttons {
  margin-top: 5px;
  margin-bottom: 5px;
  text-align: center;
}
<!DOCTYPE html>
<html>

<head>
  <link href="index.css" rel="stylesheet" type="text/css" />
</head>

<body>
  <main id="main">
    <div class="buttons">
      <button id="button1" onclick="view_table()">View table</button>
    </div>
    <div id="table">
      <table>
        <tr>
          <td>sample</td>
          <td>100</td>
          <td>10000</td>
        </tr>
        <tr>
          <td>sample</td>
          <td>100</td>
          <td>10000</td>
        </tr>
        <tr>
          <td>sample</td>
          <td>100</td>
          <td>10000</td>
        </tr>
      </table>
    </div>
    <div class="buttons">
      <button id="button2" onclick="close_table()">Hide table</button>
    </div>
  </main>
</body>
<script src="index.js "></script>

</html>

【讨论】:

  • 使用 !important 只是做相反的问题,并始终给予媒体查询优先级。它将有效地使按钮无用。
  • 哇,这似乎解决了我的问题,非常感谢。
【解决方案2】:

改为更改元素上的类。

因此您的 HTML 可能如下所示:

<div class="can-be-hidden-on-mobile is-hidden-on-mobile">
    ...
</div>

你的 JavaScript 是这样的:

document.querySelector(".can-be-hidden-on-mobile").classList.remove("is-hidden-on-mobile");

你的 CSS 是这样的:

.is-hidden-on-mobile {
    display: none;
}

@media (min-width: 400px) {
    .is-hidden-on-mobile {
        display block;
    }
}

如果 JS 运行,则删除该类,display: none 不再适用。

如果用户的显示器宽度至少为 400 像素,则 display: block; 会覆盖它。

【讨论】:

    【解决方案3】:

    也许监听窗口调整大小事件:

    window.addEventListener("resize", function() {
        if(window.innerWidth > 481) { // if we have enough space
             view_table();
        }else{
            close_table();
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2012-07-10
      • 1970-01-01
      • 2013-08-26
      • 2016-03-28
      • 2016-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-02
      相关资源
      最近更新 更多