使用 css 单击更多按钮时引入上下文菜单



我的要求是在单击树节点上的更多按钮时显示一个菜单。它应该靠近单击的节点。您可以看到更多选项图标仅悬停在树节点上。以下是我现在使用的HTML和CSS代码。

.tree ul {
margin-left: 20px;
}
.tree li {
list-style-type: none;
margin:15px;
position: relative;
cursor: pointer;
}
.tree li .submenuBtn{
margin-left:8px;
display: none;
font-weight:bolder;
}
.tree li a:hover .submenuBtn{
display: inline-block;
}
.tree li img::clicked + #contextMenu{
display: inline-block;
}
.tree li::before {
content: "";
position: absolute;
top:-7px;
left:-20px;
border-left: 1px solid #ccc;
border-bottom:1px solid #ccc;
border-radius:0 0 0 0px;
width:20px;
height:15px;
}
.tree li::after {
position:absolute;
content:"";
top:8px;
left:-20px;
border-left: 1px solid #ccc;
border-top:1px solid #ccc;
border-radius:0px 0 0 0;
width:20px;
height:100%;
}
.tree li:last-child::after  {
display:none;
}
.tree li:last-child:before{
border-radius: 0 0 0 5px;
}
ul.tree>li:first-child::before {
display:none;
}
ul.tree>li:first-child::after {
border-radius:5px 0 0 0;
}
.tree li a {
border: 1px #ccc solid;
border-radius: 5px;
padding:5px 10px;
}
.tree li a:hover, .tree li a:hover+ul li a,
.tree li a:focus, .tree li a:focus+ul li a {
background: #ccc; color: #000; 
/*border: 1px solid #000;*/
text-decoration: none;
}
.tree li a:hover+ul li::after, .tree li a:focus+ul li::after,
.tree li a:hover+ul li::before, .tree li a:focus+ul li::before 
.tree li a:hover+ul::before, .tree li a:focus+ul::before 
.tree li a:hover+ul ul::before, .tree li a:focus+ul ul::before{
/*border-color:  #000; */
/*connector color on hover*/
}
<ul class="tree">
<li><a>Parent 1 <div class="submenuBtn">:</div></a></li>
<li><a>Parent 2<div class="submenuBtn">:</div></a></li>
<li>
<a>Parent 3<div class="submenuBtn">:</div></a>
<ul>
<li>
<a>1st Child of 3<div class="submenuBtn">:</div></a>
<ul>
<li><a>1st grandchild<div class="submenuBtn">:</div></a></li>
<li><a>2nd grandchild<div class="submenuBtn">:</div></a></li>
</ul>
</li>
<li><a>2nd Child of 3<div class="submenuBtn">:</div></a></li>
<li><a>3rd Child of 3<div class="submenuBtn">:</div></a></li>
</ul>
</li>
<li>
<a>Parent 4<div class="submenuBtn">:</div></a>
<ul><li><a>Parent 4's only child<div class="submenuBtn">:</div></a></li></ul>
</li>
</ul>

是否可以为此目的重用单个上下文菜单,或者我需要将菜单与每个节点一起添加。

通过模板重用上下文菜单当然更有效,而不是将菜单作为每个节点的子元素重复。

Javascript是要走的路。

在 JS 中有很多方法可以做模板。您可以查看模板系统,例如Mustache,Handlebars或Underscore,特别是如果您需要到处模板,例如在单页应用程序中。

如果你的模板需求是一次性的,那么你可以做一个简单的Javascript解决方案,如下所示:

1. 定义模板

选项 1 - 将模板完全存储在 JS 中:

var myTemplate = '<h1>MENU</h1><div class="menu_links"><a href="link1.html" class="menu_link">Link 1</a><a href="link2.html" class="menu_link">Link 2</a></div>';

选项 2 - 将模板存储在页面中:

作为一个 HTML 元素,使用 CSS 隐藏在视图中,但仍在页面 DOM 中......

<div id="template_menu" style="visibility: hidden;"><h1>MENU</h1><div class="menu_links"><a href="link1.html" class="menu_link">Link 1</a><a href="link2.html" class="menu_link">Link 2</a></div></div>

。或者在脚本标记中,它完全将其从页面 DOM 中隐藏,不需要 CSS,但仍可由 JS 访问:

<script id="template_menu" type="x-template">
<h1>MENU</h1><div class="menu_links"><a href="link1.html" class="menu_link">Link 1</a><a href="link2.html" class="menu_link">Link 2</a></div>
</script>

选项 2 cont'd:无论哪种情况,如果模板存储在页面中,您都需要在 JS 中声明元素:

var myTemplate = document.getElementById("template_menu");

2. 在JS中使用菜单模板

最终,除了一堆其他JS函数和侦听器之外,您还可以使用模板来获得完整的体验:

function openSubMenu(e) {
// First, make a new element
var newElement = document.createElement("div");
// Apply the contents of the template to your new element
newElement.innerHTML = myTemplate.innerHTML;  
// Append the new element into the DOM. Here I'm adding it to the parent of the clicked element, but it's up to you how you want to structure things.
e.parentElement.appendChild(newElement);
}

最终可能会有一个聪明,笨拙的CSS解决方案,也许使用HTML5数据属性和隐藏的复选框,但牺牲了一些花里胡哨的东西。在模板和弹出窗口方面,相比之下,Javascript具有相对无限的潜力。

附带说明一下,我会避免任何"悬停"功能,因为任何触摸屏用户都会遇到问题,并且您将在 JS 中管理更多状态。如果你确实实现了悬停功能,你可能会发现最好在 JS 中与其他侦听器一起管理它,而不是在 CSS :hover 和 JS 之间徘徊。

最新更新