简体   繁体   English

更改媒体查询后,Javascript覆盖CSS显示属性

[英]Javascript overriding CSS display property after change of media query

I have a table that I need to be visible on a Desktop and hidden on a mobile with the option of clicking a button to show it and another to hide it on the latter. 我有一个桌子,我需要在桌面上可见,并隐藏在手机上,可以选择单击按钮显示它,另一个将其隐藏在后者上。 It appears to work fine, but when I select Button2 to hide the table in minimised view on a desktop (to imitate a mobile view) and drag the browser to increase its size to desktop the table remains hidden unless I refresh the page. 它似乎工作正常,但当我选择Button2在桌面上隐藏最小视图中的表(模仿移动视图)并拖动浏览器将其大小增加到桌面时,除非我刷新页面,否则表格将保持隐藏状态。

Basically, the javascript function close_table() sets display:none which overrides the CSS display:block @min-width 481px . 基本上,javascript函数close_table()设置display:none ,它会覆盖CSS display:block @min-width 481px

Is there a way to ensure the table is visible when increasing the browser size (after button2 has been selected) without having to refresh? 有没有办法确保在增加浏览器大小时(在选择了button2之后)表可见而无需刷新?

Any tips/help would be appreciated. 任何提示/帮助将不胜感激。

Here's sample code below 以下是示例代码

HTML : HTML:

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

CSS : CSS:

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

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

JS : JS:

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

The issue is that when you say document.getElementById('table').styles.* you are directly setting styling on an element through the DOM which has a higher priority than the media queries do through CSS. 问题在于,当你说document.getElementById('table').styles.*你直接通过DOM设置一个元素的样式,DOM的优先级高于媒体查询通过CSS做的优先级。 This means that when the media queries are triggered again nothing will happen because the DOM elements now have a higher priority styling, so the MQ rules are ignored. 这意味着当再次触发媒体查询时,不会发生任何事情,因为DOM元素现在具有更高优先级的样式,因此忽略MQ规则。

You also can't do the usual .hide .show classes because there isn't a way to add or remove classes just through media queries. 你也不能做通常的.hide .show类,因为没有办法只通过媒体查询添加或删除类。

That pretty much leaves EventListeners that will listen for a window that's being resized and execute the functionality that you want. 这几乎留下了EventListeners,它将监听正在调整大小的窗口并执行您想要的功能。

I found this article and was able to use it to write this code snippet that completes the functionality that you were looking for. 我找到了这篇文章并且能够用它来编写这段代码片段来完成你正在寻找的功能。

JavaScript has access to window.matchMedia which is where all the media related items for a document are stored.In short, this allows us to directly work with media-query-like strings inside of our JavaScript instead of solely in our CSS. JavaScript可以访问window.matchMedia,它可以存储文档的所有媒体相关项。简而言之,这使我们可以直接在JavaScript中使用类似媒体查询的字符串,而不仅仅是在我们的CSS中。

Here are some additional resources about media queries that might be helpful to skim through as you are learning this. 以下是一些有关媒体查询的其他资源,可能有助于您在学习时浏览。

For the code snippet, click full page to let you see what resizing the widow looks like. 对于代码段,请单击整页以了解调整寡妇的大小。

Using Media Queries 使用媒体查询

Media Query types 媒体查询类型

MatchMedia() 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> 

Change the classes on the element instead. 改为改变元素上的类。

So your HTML might look like this: 所以你的HTML可能如下所示:

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

And your JavaScript like this: 你的JavaScript是这样的:

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

And your CSS like this: 你的CSS是这样的:

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

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

If the JS runs, then the class is removed and the display: none no longer applies. 如果JS运行,则删除该类并且display: none不再适用。

If the user has a display that is at least 400px wide, then display: block; 如果用户的显示宽度至少为400px,则display: block; overrides it. 覆盖它。

Maybe listen to window resize event: 也许听一下窗口调整大小事件:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM