努力了解这实际上是如何运作的。代码按预期工作,但由于某些原因,当窗口调整大小,并且新函数被触发时,旧的函数仍然会触发,所以它很乱。 : - /
我确定有更好的方法来写这个。我只想要" 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/
我在我的小提琴中添加了说明,但基本上是加载页面,将鼠标悬停在栏上或单击移动版本(取决于加载页面的宽度),现在调整页面大小并尝试使用不同版本的菜单。您将看到两个版本都在运行。 : - /
答案 0 :(得分:1)
您的主要问题是您要多次添加$.hover
个事件处理程序,而不会删除它们,因此即使您将它们附加到桌面视图中,它们仍然在移动视图中处于活动状态。
但是,让我们在所有这些代码中做更多的清理工作,冒着变得有点冗长的风险:
首先,尽可能避免挂钩resize
事件,或仅执行最少的任务。此事件可能会以很高的速率发射(可能>每秒100次),并且以这样的频率操纵DOM会导致瓶颈,更不用说添加新的事件处理程序......
相反,由于您已经在使用MediaQuery API,因此请充分使用它并在onchange
处理程序中挂钩您的函数。
另外,根据您的查询,需要一个查询。要么它匹配一个,要么匹配另一个(如果你真的需要检查' (只有屏幕)',我会建议做另一个查询为此,但在文件的生命周期内以有意义的方式改变的可能性很小。)
现在我们确实正确处理了MediaQuery更改,现在是时候更改$.hover
和$.click
处理程序了:
您可以在每次返回移动视图时将其删除,并在转到桌面视图时再次添加它,但更简洁的方式是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>
&#13;
答案 1 :(得分:0)
您必须向当前窗口的resize
事件添加事件侦听器才能使其正常工作。
您的代码意味着只有在DOM准备就绪时才执行检查,这就是每次视口宽度发生变化时需要重新加载的原因。
$(window).resize(function() {
// your code
// e.g check the width: console.log($(this).innerWidth());
});
// OR
$(window).resize(() => console.log($(this).innerWidth()))