我正在尝试使用导航菜单创建一个满足以下两个要求的响应式网站:
我希望移动设备上的性能良好 - 特别是在iOS上 - 这意味着动画应该使用GPU-accelerated translate3d transform CSS过渡。
设置它是一块蛋糕,而且大多数情况下效果很好。我使用z-index: 1
和transform: translate3d(0,-100%,0)
隐藏了标题后面的菜单,z-index: 2
处于默认关闭状态,然后transform: translate3d(0,0,0)
将菜单设置为打开状态。
但我只是遇到一个问题:当我调整Chrome浏览器窗口的大小并启动移动媒体查询时,菜单会从打开状态设置为关闭状态。
将浏览器窗口的大小调整为小于600px宽,以查看操作中的问题:
我想我知道为什么会发生这种情况:当移动媒体查询启动时,浏览器会看到.nav
当前未处于活动状态,因此会将其设置为默认关闭状态。我尝试使用display:none
和display:block
来尝试不同的媒体查询状态,但这似乎完全破坏了动画。
如何在调整浏览器窗口大小时阻止导航菜单的“关闭”动画被触发?
答案 0 :(得分:9)
干得好,很干净。我可以偷了吗? : - )
无论如何,这是你的解决方案demo。
我刚刚过渡到另一个班级:
.nav {
/* stuff */
z-index: 1;
transform: translate3d(0,-100%,0);
-webkit-transform: translate3d(0,-100%,0);
}
.nav.active {
transform: translate3d(0,0,0);
-webkit-transform: translate3d(0,0,0);
}
.nav.activated {
transition: transform 400ms linear;
-webkit-transition: -webkit-transform 400ms linear;
}
首先可以添加到元素“Toggle”:
function toggle(){
$(".nav").addClass("activated").toggleClass("active");
}
P.S。如果您不希望在用户打开菜单后再进行转换,然后再次调整窗口大小,则可以使用Modernizr的mq method:
$(window).on('resize',function(){
if(Modernizr.mq('(min-width:600px)')) $(".nav").removeClass("activated");
});
答案 1 :(得分:2)
参考Giona提到的副作用:
P.S。如果您不想在用户打开菜单后再进行转换,然后再次调整窗口大小(...)
有一种更简洁的方法来解决这个问题,而不会触发每个resize事件。您可以在转换结束后删除要转换的类resposible(完整演示here):
$(function()
{
$(".nav").on("transitionend", function() {
$(this).removeClass("activated");
});
}
)();
答案 2 :(得分:0)
通过结合Giona和Janusz Kacalak(以及Justin Bull的评论)的答案,我们可以进一步优化代码,以使导航栏永远不会从打开状态变为关闭状态(不仅限于动画)。第一次,这就是Giona的代码)。
function toggle() {
var navbar = $(".nav");
if (navbar.hasClass("active")) {
// Closing the nav bar.
navbar.removeClass("active");
// Listening for a transition.
// Use `.one` here because we only want this to be called once.
navbar.one(whichTransitionEvent(), function() {
// Remove animation property after the nav bar is closed.
navbar.removeClass("activated");
});
} else {
// Opening the nav bar.
navbar.addClass("activated").addClass("active");
}
}
// Ref: https://davidwalsh.name/css-animation-callback
function whichTransitionEvent() {
var t;
var el = document.createElement('fakeelement');
var transitions = {
'transition': 'transitionend',
'OTransition': 'oTransitionEnd',
'MozTransition': 'transitionend',
'WebkitTransition': 'webkitTransitionEnd'
};
for (t in transitions) {
if (el.style[t] !== undefined) {
return transitions[t];
}
}
}
body { margin: 0; }
.toggle { display: none; }
.nav { list-style-type: none; margin: 0; padding: 0; }
.nav li { float: left; margin: 0; padding: 20px; background: #fdd; }
.nav li:nth-child(2n) { background: #dfd; }
@media only screen and (max-width: 599px)
{
.toggle {
display: block;
position: relative;
z-index: 2;
padding: 20px;
background: #eee;
}
.nav li {
display: block;
float: none;
}
.nav {
display: block;
position: relative;
z-index: 1;
transform: translate3d(0,-100%,0);
-webkit-transform: translate3d(0,-100%,0);
}
.nav.active {
transform: translate3d(0,0,0);
-webkit-transform: translate3d(0,0,0);
}
.nav.activated {
transition: transform 400ms linear;
-webkit-transition: -webkit-transform 400ms linear;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href="#" class="toggle" onclick="javascript:toggle();return false;">Toggle menu</a>
<ul class="nav">
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
</ul>