デモ
See the Pen Menu-2 Multilayer by YugetaKoji (@geta1972) on CodePen.
ソースコード
<html lang="en">
<head>
<meta charset="utf-8">
<title>HTML-parts Header</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="menu2.css">
<script src="menu2.js"></script>
</head>
<body>
<div class="menu-bar">
<ul>
<li>
<a href="javascript:void(0)">Menu-1</a>
<ul>
<li><a href="#menu-1-1">Menu-1-1</a></li>
<li><a href="#menu-1-2">Menu-1-2</a></li>
</ul>
</li>
<li>
<a href="#menu-2">Menu-2</a>
</li>
</ul>
<ul>
<li>
<a href="javascript:void(0)">Menu-3</a>
<ul>
<li><a href="#menu-3-1">Menu-3-1</a></li>
<li>
<a href="#menu-3-2">Menu-3-2</a>
<ul>
<li><a href="#menu-3-2-1">Menu-3-2-1</a></li>
<li><a href="#menu-3-2-1">Menu-3-2-2</a></li>
<li>
<a href="#menu-3-2-3">Menu-3-2-3</a>
<ul>
<li><a href="#menu-3-2-3-1">Menu-3-2-3-1</a></li>
<li><a href="#menu-3-2-3-2">Menu-3-2-3-2</a></li>
<li><a href="#menu-3-2-3-3">Menu-3-2-3-3</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
html,body{
margin : 0;
padding : 0;
border : 0;
width : 100%;
height : 100%;
}
*, *:before, *:after {
-webkit-box-sizing : border-box;
-moz-box-sizing : border-box;
-o-box-sizing : border-box;
-ms-box-sizing : border-box;
box-sizing : border-box;
}
.menu-bar{
height : 60px;
border-bottom : 1px solid #AAA;
line-height : 60px;
display : -webkit-flex;
display : flex;
-webkit-justify-content : center;
justify-content : center;
-webkit-align-items : center;
align-items : center;
}
/* basic */
.menu-bar ul{
margin : 0;
padding : 0;
border : 0;
}
.menu-bar ul li{
margin : 0;
padding : 0;
border : 0;
list-style : none;
}
.menu-bar ul li a{
display : inline-block;
height : 100%;
padding : 0 8px;
cursor : pointer;
text-decoration : none;
color : #666;
white-space : nowrap;
}
.menu-bar ul li a:hover{
/* background-color : #eee; */
color : #C66;
}
/* top-menu */
.menu-bar > ul{
display : flex;
height : 100%;
min-width : 100px;
}
.menu-bar > ul > li{
position : relative;
}
.menu-bar > ul > li > a{
min-width : 100px;
text-align:center;
}
/* .menu-bar > ul > li > a:hover{
background-color:#eee;
} */
.menu-bar ul > li[data-view="1"] > a{
background-color:#eee;
}
.menu-bar ul > li[data-view="0"] > a{
animation: menu-noactive 0.3s linear forwards;
}
.menu-bar ul > li.dropdown > a:after,
.menu-bar ul > li[data-dropdown="1"] > a:after{
content: "";
display: inline-block;
width: 0;
height: 0;
vertical-align: middle;
border-top: 6px dashed;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
box-sizing: border-box;
margin-left:4px;
}
/* second-menu */
.menu-bar > ul > li ul{
position : absolute;
/* left : 0; */
line-height : 30px;
border:1px solid #aaa;
border-width:1px 1px 0;
/* box-shadow : 2px 2px 8px rgba(0,0,0,0.3); */
opacity : 0.0;
visibility : hidden;
transform : scale(0);
transform-origin:top;
}
.menu-bar > ul > li > ul{
/* position : absolute; */
left : 0;
/* line-height : 30px;
border:1px solid #aaa;
border-width:1px 1px 0;
box-shadow : 2px 2px 8px rgba(0,0,0,0.4);
opacity : 0.0;
visibility : hidden;
transform : scale(0);
transform-origin:top; */
}
.menu-bar ul > li[data-view="1"] > ul{
visibility : visible;
opacity : 1.0;
}
.menu-bar ul > li[data-view="0"] > ul{
animation: menu-close 0.3s linear forwards;
}
.menu-bar ul > li[data-view="1"] > ul{
animation: menu-list-open 0.1s linear forwards;
}
.menu-bar ul > li[data-view="0"] > ul{
animation: menu-list-close 0.1s linear forwards;
}
.menu-bar > ul > li > ul li{
position:relative;
border-bottom : 1px solid #aaa;
}
.menu-bar > ul > li > ul li > a{
min-width : 120px;
text-align:center;
}
/* third-menu */
.menu-bar > ul > li > ul > li ul{
position:absolute;
top:0;
left:100%;
}
.menu-bar > ul > li > ul > li ul > li{
position:relative;
min-width:120px;
}
@keyframes menu-noactive{
0%{
background-color:#eee;
}
100%{
background-color:rgba(255,255,255,0.0);
}
}
@keyframes menu-close{
0%{
opacity:1.0;
visibility:visible;
}
100%{
opacity:0.0;
visibility:hidden;
}
}
@keyframes menu-list-open{
0%{
transform : scaleY(0);
}
100%{
transform : scaleY(1);
}
}
@keyframes menu-list-close{
0%{
transform : scaleY(1);
}
100%{
transform : scaleY(0);
}
}
;(function(){
// ページ内にjsライブラリの読み込み
var $$addScript = function(file){
var s = document.createElement("script");
s.src = file;
document.body.appendChild(s);
}
// イベントライブラリ
var $$event = function(target, mode, func){
//other Browser
if (typeof target.addEventListener !== "undefined"){
target.addEventListener(mode, func, false);
}
else if(typeof target.attachEvent !== "undefined"){
target.attachEvent('on' + mode, function(){func.call(target , window.event)});
}
};
var $$ = function(){
var state = document.readyState;
if(state === "complete"){
this.start();
}
else if(state === "interactive"){
$$event(window , "DOMContentLoaded" , (function(e){this.start(e)}).bind(this));
}
else{
$$event(window , "load" , (function(e){this.start(e)}).bind(this));
}
};
$$.prototype.start = function(){
// dropdown-set
this.set_dropdown();
// dropdown-click
this.set_dropdown_click();
// top-menu
// var links = document.querySelectorAll(".menu-bar ul > li[data-dropdown='1'] > a");
var links = document.querySelectorAll(".menu-bar ul > li > a");
for(var i=0; i<links.length; i++){
$$event(links[i] , "click" , (function(e){this.set_top_menu_toggle(e)}).bind(this));
}
// other-click
$$event(window , "click" , (function(e){this.checkClick(e)}).bind(this));
};
$$.prototype.set_top_menu_toggle = function(e){
var currentTarget = e.currentTarget;
if(!currentTarget || currentTarget.parentNode.getAttribute("data-dropdown") !== "1"){
this.set_top_menu_hidden();
}
var top_menus = document.querySelectorAll(".menu-bar ul > li");
for(var i=0; i<top_menus.length; i++){
// 対象リンククリック
if(top_menus[i] === currentTarget.parentNode){
if(top_menus[i].getAttribute("data-view") !== "1"){
this.set_top_menu_view(top_menus[i] , true);
}
else{
this.set_top_menu_view(top_menus[i] , false);
}
}
// 対象の親階層は処理しない
else if(this.checkHierarchy(currentTarget , top_menus[i])){
continue;
}
// 対象外リンククリック
else{
this.set_top_menu_view(top_menus[i] , false);
}
}
};
$$.prototype.checkHierarchy = function(currentTarget , menuElement){
while(!currentTarget.matches(".menu-bar")){
if(currentTarget === menuElement){
return true;
}
currentTarget = currentTarget.parentNode;
}
return false;
};
// bool @ [true:active , false:unactive]
$$.prototype.set_top_menu_view = function(linkElm , bool){
if(!linkElm){return;}
if(bool === true){
linkElm.setAttribute("data-view" , "1");
}
else{
linkElm.setAttribute("data-view" , "0");
}
};
// all-link-hidden
$$.prototype.set_top_menu_hidden = function(){
var listElm = document.querySelectorAll(".menu-bar ul > li");
for(var i=0; i<listElm.length; i++){
if(listElm[i].getAttribute("data-dropdown") !== "1"){continue;}
listElm[i].setAttribute("data-view" , "0");
}
};
// bool @ [true:view , false:hidden]
$$.prototype.set_top_menu_active = function(dropdowns , currentTarget){
if(!dropdowns || !dropdowns.length){return;}
for(var i=0; i<dropdowns.length; i++){
if(!currentTarget || dropdowns[i].getAttribute("data-active") === "1"){
dropdowns[i].setAttribute("data-active" , "0");
}
else{
dropdowns[i].setAttribute("data-active" , "1");
}
}
};
// window-event
$$.prototype.checkClick = function(e){
var target = e.target;
if(target && target.matches(".menu-bar ul > li *")){
return;
}
if(!target || !target.matches(".menu-bar ul > li > a")){
this.set_top_menu_hidden();
}
};
$$.prototype.set_dropdown = function(){
var top_menus = document.querySelectorAll(".menu-bar ul > li");
for(var i=0; i<top_menus.length; i++){
var listsElm = top_menus[i].querySelectorAll(":scope > ul");
if(!listsElm.length){continue;}
top_menus[i].setAttribute("data-dropdown" , "1");
}
};
$$.prototype.set_dropdown_click = function(){
var dropdowns = document.querySelectorAll(".menu-bar ul li[data-dropdown='1']");
for(var i=0; i<dropdowns.length; i++){
var a = dropdowns[i].querySelector(":scope > a");
a.href = "javascript:void(0)";
}
};
new $$;
})();
0 件のコメント:
コメントを投稿