很难理解它实际上是如何工作的。代码按预期工作,但由于某种原因,当调整窗口大小并触发新函数时,旧函数仍然在触发,所以一团糟。 :-/
我确信有更好的方法来写这个。我只希望“isMobile”在 max-width: 1024 时运行,“isNotMobile”在 max-width 大于 1024 时运行,但只有一个运行,而不是同时运行。有更好的方法吗?
$(document).ready(function(){
$(window).resize(function() {
var isMobile = window.matchMedia("only screen and (max-width: 1024px)");
var isNotMobile = window.matchMedia("only screen and (min-width: 1024px)");
if (isMobile.matches) {
$('#wpi-page-left').removeClass("active");
$('#wpi-page-left').addClass("not-active");
$( '#wpi-page-center' ).click(function(e) {
var $this = $('#wpi-page-left');
if ($this.hasClass('active')) {
$('#wpi-page-left').removeClass('active');
$('#sidebar').removeClass('active');
$('#wpi-page-left').addClass('not-active');
}
});
$( '#mobile-toggle-btn' ).click(function(e){
var $this = $('#wpi-page-left');
if ($this.hasClass('not-active')) {
$('#wpi-page-left').removeClass('not-active');
$('#wpi-page-left').addClass('active');
$('#sidebar').addClass('active');
} else if ($this.hasClass('active')) {
$('#wpi-page-left').removeClass('active');
$('#sidebar').removeClass('active');
$('#wpi-page-left').addClass('not-active');
}
});
} else if (isNotMobile.matches) {
setTimeout(function() {
$( '#wpi-page-left' ).removeClass( 'active' );
}, 1000);
var timer;
var delay = 350;
$('#wpi-page-left').hover(function() {
timer = setTimeout(function() {
$('#wpi-page-left').addClass( 'active' );
$('#wpi-page-left').removeClass( 'not-active' );
}, delay);
}, function() {
$('#wpi-page-left').removeClass( 'active' );
$('#wpi-page-left').addClass( 'not-active' );
clearTimeout(timer);
});
}
$("#dimensions").html($(window).width());
}).resize();
});
更新:
这是一个显示问题的 FIDDLE: https://jsfiddle.net/hwqegaza/9/
我在 fiddle 中添加了说明,但基本上加载页面,然后将鼠标悬停在栏上或单击移动版本(取决于页面加载的宽度),现在调整页面大小并尝试使用不同版本的菜单。您会看到两个版本都在运行。 :-/
最佳答案
您的主要问题是您多次添加 $.hover
事件处理程序,但从未删除它们,因此即使您将它们附加到桌面 View ,它们仍然在桌面 View 中处于事件状态。移动 View 。
但是,让我们对所有这些代码进行更多清理,冒着变得有点冗长的风险:
首先,尽可能避免 Hook resize
事件,或仅执行最少的任务。该事件可能会以很高的速率触发(可以>每秒 100 次),并且以这样的频率操作 DOM 可能会导致瓶颈,更不用说添加新的事件处理程序了...
相反,因为您已经在使用 MediaQuery API ,充分使用它并将您的函数挂接到其 onchange
中处理程序。
另外,根据您的查询,需要一个。它要么匹配一个,要么匹配另一个 (如果您确实需要检查“(仅屏幕)”,我建议为此进行另一个查询,但有它在文档的生命周期中以有意义的方式发生变化的可能性很小)。
现在我们已经正确处理了 MediaQuery 更改,是时候更改 $.hover
和 $.click
处理程序了:
您可以在每次返回移动 View 时将其删除,并在转到桌面 View 时再次添加它,但更简洁的方式 IMO 是仅附加这些事件一次,并简单地在处理程序函数本身中处理这两种情况,然后退出当观点错误时就过早地采取行动。
它可能会给我们类似的东西
$(document).ready(function() {
// a single MediaQuery
var isMobile = window.matchMedia("only screen and (max-width: 800px)");
// toggle the classes when our MediaQuery will change
isMobile.onchange = toggleMobile;
toggleMobile(); // do the initial one
function toggleMobile() {
if (isMobile.matches) {
$('#wpi-page-left').removeClass("active");
$('#wpi-page-left').addClass("not-active");
$('#wpi-page-center').click(function(e) {
var $this = $('#wpi-page-left');
if ($this.hasClass('active')) {
$('#wpi-page-left').removeClass('active');
$('#sidebar').removeClass('active');
$('#wpi-page-left').addClass('not-active');
}
});
} else { // if we're not in mobile, then we are in desktop
setTimeout(function() {
$('#wpi-page-left').removeClass('active');
}, 1000);
}
$("#dimensions").html(isMobile.matches ? 'Mobile' : 'Desktop');
};
// this needs to be called only once
(function attachHoverHandlers() {
var timer;
var delay = 350;
// attach the event listeners
$('#wpi-page-left').hover(onhoverin, onhoverout);
function onhoverin() {
if (isMobile.matches) return; // if mobile view, then do nothing
timer = setTimeout(function() {
$('#wpi-page-left').addClass('active');
$('#wpi-page-left').removeClass('not-active');
}, delay);
}
function onhoverout() {
if (isMobile.matches) return; // if mobile view, then do nothing
$('#wpi-page-left').removeClass('active');
$('#wpi-page-left').addClass('not-active');
clearTimeout(timer);
}
})();
// So does this
$('#mobile-toggle-btn').click(handleMobileClick);
function handleMobileClick(e) {
if (!isMobile.matches) return;
var $this = $('#wpi-page-left');
if ($this.hasClass('not-active')) {
$('#wpi-page-left').removeClass('not-active');
$('#wpi-page-left').addClass('active');
$('#sidebar').addClass('active');
} else if ($this.hasClass('active')) {
$('#wpi-page-left').removeClass('active');
$('#sidebar').removeClass('active');
$('#wpi-page-left').addClass('not-active');
}
}
})
html,
body {
display: flex;
flex-direction: row;
height: 100vh;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
font-family: helvetica;
}
.label {
padding-left: 5px;
}
#wpi-page-left {
flex: 0 80px;
width: 80px;
background: #2E323C;
overflow-y: auto;
overflow-x: hidden;
-webkit-transition: all 0.15s ease;
-moz-transition: all 0.15s ease;
-ie-transition: all 0.15s ease;
-o-transition: all 0.15s ease;
transition: all 0.15s ease;
}
#wpi-page-left .fa,
#wpi-page-left .label {
color: #FFF;
}
#wpi-page-left ul {
list-style-type: none;
margin: 0;
padding: 0;
}
#wpi-page-left ul>li a {
display: inline-block;
color: #e6e6e6;
text-decoration: none;
padding: 8px 0;
width: 100%;
}
#wpi-page-left ul>li a:hover {
color: #FFF;
background: #181a1f;
}
#wpi-page-left #wrap-menu {
display: flex;
flex-direction: column;
flex: 1 auto;
height: 100%;
}
#wpi-page-left #wrap-menu #logo {
flex: 0 auto;
display: none;
margin: 10px 0;
}
#wpi-page-left #wrap-menu #logo-inactive {
flex: 0 auto;
text-align: center;
width: 100%;
margin: 10px 0;
}
#wpi-page-left #wrap-menu #menu {
display: flex;
flex-direction: column;
flex: 1 auto;
}
#wpi-page-left #wrap-menu #menu ul#sidebar {
flex: 1 250px;
}
#wpi-page-left #wrap-menu #menu ul#sidebar>li a {
padding: 8px;
}
#wpi-page-left #wrap-menu #menu ul#sidebar #mobile-logo-ext {
display: none;
}
#wpi-page-left #wrap-menu #menu ul#mobile-bar {
list-style-type: none;
margin: 10px 0 60px 0;
display: none;
width: 60px;
}
#wpi-page-left #wrap-menu #menu ul#mobile-bar>li {
width: 100%;
}
#wpi-page-left ul#sidebar {
display: none;
}
#wpi-page-left ul#sidebar-inactive {
display: block;
}
#wpi-page-left ul#sidebar-inactive>li {
text-align: center;
}
#wpi-page-left.active {
flex: 0 210px;
width: 210px;
}
#wpi-page-left.active #wrap-menu #logo {
display: block;
}
#wpi-page-left.active #wrap-menu #logo-inactive {
display: none;
}
#wpi-page-left.active #wrap-menu ul#sidebar {
display: block;
}
#wpi-page-left.active #wrap-menu ul#sidebar-inactive {
display: none;
}
#wpi-page-center {
display: flex;
flex-direction: column;
flex: 1;
background: #F1F5FA;
overflow-y: auto;
padding: 10px;
}
#wpi-page-center .panel {
flex: 1 auto;
background: #FFF;
border: 1px solid #cbdaed;
padding: 10px;
}
@media screen and (max-width: 800px) {
#wpi-page-left {
flex: 0 80px;
width: 80px;
overflow: hidden;
}
#wpi-page-left #logo {
display: none;
}
#wpi-page-left #logo-inactive {
display: none;
}
#wpi-page-left #wrap-menu {
display: flex;
flex-direction: column;
flex: 1 auto;
height: 100%;
min-width: 80px;
}
#wpi-page-left #wrap-menu #logo {
flex: 0 auto;
}
#wpi-page-left #wrap-menu #logo-inactive {
flex: 0 auto;
}
#wpi-page-left #wrap-menu #menu {
display: flex;
flex-direction: column;
flex: 1 auto;
min-width: 80px;
}
#wpi-page-left #wrap-menu #menu ul#mobile-bar {
display: block;
position: relative;
z-index: 120;
background: #2E323C;
flex: 1 80px;
width: 80px;
padding: 0;
margin: 0;
border-right: 1px solid #181a1f;
height: 100%;
}
#wpi-page-left #wrap-menu #menu ul#mobile-bar li {
width: 100%;
text-align: center;
}
#wpi-page-left #wrap-menu #menu ul#mobile-bar li:first-child {
text-align: center;
height: 61px;
padding: 10px 0;
border-bottom: 1px solid #181a1f;
}
#wpi-page-left #wrap-menu #menu ul#mobile-bar li:nth-child(2) {
margin-top: 10px;
padding-top: 8px;
padding-bottom: 8px;
}
#wpi-page-left #wrap-menu #menu ul#mobile-bar li a {
display: inline-block;
border-width: 0;
background: transparent;
width: 100%;
padding: 8px 0;
color: whitesmoke;
}
#wpi-page-left #wrap-menu #menu ul#mobile-bar li a:hover {
color: #FFF;
}
#wpi-page-left #wrap-menu #menu ul#sidebar {
position: fixed;
background: #2E323C;
left: -330px;
top: 0;
bottom: 0;
margin: 0;
padding-top: 5px;
z-index: 100;
flex: 1 250px;
width: 250px;
overflow-x: hidden;
-webkit-transition: all 0.15s ease;
-moz-transition: all 0.15s ease;
-ie-transition: all 0.15s ease;
-o-transition: all 0.15s ease;
transition: all 0.15s ease;
}
#wpi-page-left #wrap-menu #menu ul#sidebar.active {
left: 80px;
overflow-y: auto;
}
#wpi-page-left #wrap-menu #menu ul#sidebar li#mobile-logo-ext {
display: block;
overflow: visible;
}
#wpi-page-left #wrap-menu #menu ul#sidebar-inactive {
display: none;
}
#wpi-page-left #wrap-menu #menu.active ul#sidebar {
left: 50px;
order: 2;
}
#wpi-page-left.active {
flex: 0 80px;
width: 80px;
}
#wpi-page-left.active #wrap-menu #logo {
display: none;
flex: 0 auto;
}
#wpi-page-left.active #wrap-menu #logo-inactive {
display: none;
flex: 0 auto;
}
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wpi-page-left">
<div id="wrap-menu">
<div id="logo">
<span class="fa fa-css3 fa-2x"></span><span class="label">COMPANY NAME</span>
</div>
<div id="logo-inactive">
<span class="fa fa-css3 fa-2x"></span>
</div>
<div id="menu">
<ul id="mobile-bar">
<li>
<span class="fa fa-css3 fa-2x"></span>
</li>
<li>
<a id="mobile-toggle-btn" href="#!"><i class="fa fa-bars fa-fw fa-lg"></i></a>
</li>
</ul>
<ul id="sidebar">
<li id="mobile-logo-ext">
<span class="label">COMPANY</span>
</li>
<li id="item1">
<a href="#!">
<span class="fa fa-file-word-o fa-fw"></span><span class="label">Menu Item 1</span>
</a>
</li>
<li id="item2">
<a href="#!">
<span class="fa fa-file-archive-o fa-fw"></span><span class="label">Menu Item 2</span>
</a>
</li>
<li id="item3">
<a href="#!">
<span class="fa fa-file-pdf-o fa-fw"></span><span class="label">Menu Item 3</span>
</a>
</li>
<li id="item4">
<a href="#!">
<span class="fa fa-file-code-o fa-fw"></span><span class="label">Menu Item 4</span>
</a>
</li>
</ul>
<ul id="sidebar-inactive">
<li id="item1">
<a href="#!">
<span class="fa fa-file-word-o fa-fw"></span>
</a>
</li>
<li id="item2">
<a href="#!">
<span class="fa fa-file-archive-o fa-fw"></span>
</a>
</li>
<li id="item3">
<a href="#!">
<span class="fa fa-file-pdf-o fa-fw"></span>
</a>
</li>
<li id="item4">
<a href="#!">
<span class="fa fa-file-code-o fa-fw"></span>
</a>
</li>
</ul>
</div>
</div>
</div>
<div id="wpi-page-center">
<div class="panel">
<h2>Page mode: <span id="dimensions"></span></h2>
<p>
Resize from above 800px to below 800px, or vice versa. You'll see that both are running. The hover stuff shouldn't be active when below 800px, but it is... :(
</p>
</div>
</div>
关于javascript - jQuery window.matchMedia 冲突函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48760984/