Neste artigo, vou dizer como é simples e fácil criar menus dinâmicos lineares que suportam não apenas eventos de mouse, mas também ponteiros para versões móveis.
E assim: Menu Dinâmico Simples da RevolveR Labs.
Tudo começa com o layout. Deve ser semântico, leve e moderno.
<nav class="dynamic-menu">
<ul>
<li><a href="https://revolvercmf.ru">RevolveR Labs</a></li>
<li><a href="#">Ultra newest solutions</a></li>
<li><a href="#">The way of incredible</a></li>
<li><a href="#">In search of the best</a></li>
<li><a href="#">Progressive RevolveR frontends</a></li>
<li><a href="#">Developing of new era</a></li>
</ul>
</nav>
Usamos uma lista com marcadores padrão e HTML 5 como um elemento de wrapper e, para fazer o menu flutuar, escreveremos imediatamente estilos CSS que puxam o menu para fora da tela em toda a largura da lista de elementos e ocultam todos os desnecessários para o escopo:
.dynamic-menu {
display: inline-block;
text-align: center;
overflow: hidden;
margin: 0 auto;
height: 3vw;
width: 80%;
}
.dynamic-menu ul {
transition: all 2.5s ease-in-out;
position: relative;
list-style: none;
width: 900vw;
padding: 0;
margin: 0;
left: 0vw;
}
.dynamic-menu ul li {
box-shadow: 0 0 0.1vw #333;
border: .1vw dashed #fff;
background: #a2a2a2;
margin-bottom: 1vw;
display: inline-block;
border-radius: .2vw;
margin-right: .5vw;
padding: .2vw 1vw;
background: #888;
float: left;
}
.dynamic-menu ul li a {
text-shadow: 0 0 0.2vw #fff;
font: normal 2vw Helvetica;
text-decoration: none;
color: #006400;
}
.dynamic-menu ul li a:hover {
text-decoration: underline;
color: #674c2be0;
}
CSS . . , touch.
Handler desktop
RevolveR API :
let launch = RR.browser;
RR.menuMove = null;
if( !RR.isM ) {
RR.event('.dynamic-menu ul', 'mousedown', (e) => {
e.preventDefault();
if( !RR.menuMove ) {
RR.menuLeft = RR.curxy[0];
RR.MenuMoveObserver = RR.event('body', 'mousemove', (e) => {
e.preventDefault();
RR.styleApply('.dynamic-menu ul', ['transition: all 0s ease']);
RR.menuMove = true;
RR.menuPosition = ( RR.menuLeft - RR.curxy[0] ) *-1;
RR.styleApply('.dynamic-menu ul', ['left:'+ RR.menuPosition +'px']);
RR.event('body', 'mouseup', (e) => {
e.preventDefault();
if( e.target.tagName === 'A' && !RR.touchFreeze ) {
//R.loadURI(target.href, target.title);
console.log(e.target.href);
RR.touchFreeze = true;
RR.menuMove = null;
}
void setTimeout(() => {
RR.menuMove = null;
}, 50);
void setTimeout(() => {
if( !RR.menuMove ) {
RR.styleApply('.dynamic-menu ul', ['left: 0px', 'transition: all 2.5s cubic-bezier(0.175, 0.885, 0.32, 1.275)']);
}
}, 2500);
});
});
}
});
}
event RR.browser(). RR.curxy.
, , , , .
RR.MenuMoveObserver event , MD5 hash , X. mouseup.
. , X, left .
handler
, .
, , touch .
if( RR.isM ) {
RR.event('.dynamic-menu ul', 'touchstart', (e) => {
e.preventDefault();
RR.menuMove = null;
RR.event('body', 'touchend', (e) => {
e.preventDefault();
if( !RR.menuMove ) {
RR.touchFreeze = null;
let target = e.changedTouches[0].target;
if( RR.isO(RR.MenuMoveObserver) ) {
for( i of RR.MenuMoveObserver ) {
RR.detachEvent( i[ 2 ] );
}
}
if( target.tagName === 'A' && !RR.touchFreeze ) {
//R.loadURI(target.href, target.title);
console.log(e.target.href);
RR.touchFreeze = true;
RR.menuMove = null;
}
void setTimeout(() => {
if( !RR.menuMove ) {
RR.styleApply('.dynamic-menu ul', ['left: 0px', 'transition: all 2.5s cubic-bezier(0.175, 0.885, 0.32, 1.275)']);
//RR.animate('.dynamic-menu ul', ['left:0px:1000:wobble']);
}
}, 2500);
}
});
if( !RR.menuMove ) {
RR.menuLeft = e.changedTouches[0].screenX;
RR.MenuMoveObserver = RR.event('body', 'touchmove', (e) => {
e.preventDefault();
RR.styleApply('.dynamic-menu ul', ['transition: all 0s ease']);
RR.menuMove = true;
RR.menuPosition = ( RR.menuLeft - e.changedTouches[0].screenX ) *-1;
RR.styleApply('.dynamic-menu ul', ['left:'+ RR.menuPosition +'px']);
RR.event('body', 'touchend', (e) => {
RR.menuMove = null;
});
});
}
});
}
. event.target touch. easing :
void setTimeout(() => {
if( !RR.menuMove ) {
RR.styleApply('.dynamic-menu ul', ['left: 0px', 'transition: all 2.5s cubic-bezier(0.175, 0.885, 0.32, 1.275)']);
}
}, 2500);
Demo
Muitos de vocês usam plug-ins prontos ou blocos de layout embutidos com menus de hambúrguer, mas menus lineares dinâmicos são tão bons e economizam espaço em interfaces. Muitos de vocês provavelmente achariam difícil implementar tais menus devido à diferença nos ouvintes de eventos e à incapacidade de usar sinalizadores. Este exemplo teve como objetivo mostrar que usando JavaScript comum é possível, sem nenhuma qualificação proibitiva, implementar as mesmas coisas que em aplicativos Android convenientes, e o trabalho magistral com animações permite criar efeitos de transição impressionantes e vários ganchos de evento para quaisquer gatilhos.