【发布时间】:2020-03-26 14:28:56
【问题描述】:
我正在尝试使用 Vanilla Javascript、CSS 和 HTML 构建导航 UI,但在需要上下移动 div 元素并根据它们的当前状态 active 或 @987654322 更改它们的顶部和右侧位置时卡住了@
const diamond = document.getElementById('main-diamond'),
pointerArrowTop = document.getElementById('pointer-arrow-top'),
pointerArrowRight = document.getElementById('pointer-arrow-right'),
pointerArrowBottom = document.getElementById('pointer-arrow-bottom'),
pointerArrowLeft = document.getElementById('pointer-arrow-left'),
mouseoverEvent = new Event('mouseover'),
radius = 200, // The radius of the semi circle
nodes = document.querySelectorAll('[data-first]'), // number of nodes in the code
nodeContainerFirst = document.querySelector('[data-node-level="first"]'), // Get the container of the first level nodes
nodeWidth = nodes[0].clientWidth, // Defined width of the node
nodeHeight = nodes[0].clientHeight, // Defined width of the node
angle = Math.round( 180 / (nodes.length - 1)); // Distance of the gap between nodes;
pointerArrowTop.addEventListener('mouseover', function(){
diamond.style["boxShadow"] = "-2px -2px 4px rgba(255,255,255,0.4)";
});
pointerArrowTop.addEventListener('mouseout', function(){
diamond.style["boxShadow"] = null;
diamond.style.transform = "rotate(45deg)";
});
pointerArrowTop.addEventListener('click', function(e){
let activeNode = document.querySelector('[data-state="active"]'),
inactiveNodes = document.querySelectorAll('[data-state="inactive"]'),
siblingNode = activeNode.nextElementSibling,
previousSiblingNode = activeNode.previousElementSibling;
activeNode.setAttribute('style', 'top: -180px; left: -40px');
activeNode.dataset.state = 'inactive';
siblingNode.setAttribute('style', 'top: -180px; left: 0px;');
siblingNode.dataset.state = 'active';
inactiveNodes.forEach(function(node, index){
if(previousSiblingNode){
if(index != 2 && index != 0 && index != 1){
let leftVal = Math.round(index * -40);
node.setAttribute('style', 'left: '+leftVal+'px; top: -'+((index+1)+180 *(index))+'px;');
}
}else{
if(index != 0){
let leftVal = Math.round(index * -40);
node.setAttribute('style', 'left: '+leftVal+'px; top: -'+((index+1)+180*(index))+'px;');
}
}
});
});
pointerArrowRight.addEventListener('mouseover', function(){
diamond.style["boxShadow"] = "2px -2px 4px rgba(255,255,255,0.4)";
});
pointerArrowRight.addEventListener('mouseout', function(){
diamond.style["boxShadow"] = null;
});
pointerArrowBottom.addEventListener('mouseover', function(){
diamond.style["boxShadow"] = "2px 2px 4px rgba(255,255,255,0.4)";
});
pointerArrowBottom.addEventListener('mouseout', function(){
diamond.style["boxShadow"] = null;
});
pointerArrowLeft.addEventListener('mouseover', function(){
diamond.style["boxShadow"] = "-2px 2px 4px rgba(255,255,255,0.4)";
});
pointerArrowLeft.addEventListener('mouseout', function(){
diamond.style["boxShadow"] = null;
});
document.addEventListener("DOMContentLoaded", function() {
nodes.forEach(function(node, index) {
let leftVal = Math.round(index * -40);
node.setAttribute('style', 'left: '+leftVal+'px; top: -'+(index+1)+'px;');
});
});
@import url('https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap');
body {
height: 100vh;
width: 100vw;
margin: 0;
padding: 0;
font-family: 'Montserrat', sans-serif;
}
body.dark-mode {
background: linear-gradient(to bottom right,#15071a,#1a0f29,#1c2b3f,#064a5b) #f7f7f7;
color: #f7f7f7;
}
.d-flex-center {
display: flex;
align-items: center;
}
.centerPointMarker {
position: absolute;
width: 10px;
height: 10px;
background-color: aqua;
border-radius: 50%;
}
.app-container {
width: calc(100% - 34px);
max-width: 960px;
height: 100vh;
margin: 0px 17px;
}
header {
height: 100px;
width: 100%;
display: block;
margin-bottom: 20px;
}
.p-t-180 {
padding-top: 180px;
}
main {
display: block;
overflow-y: hidden;
max-height: 700px;
}
.nav-container {
width: 114px;
height: 180px;
display: flex;
align-items: center;
}
.nav-container #main-diamond {
width: 83px;
height: 83px;
border: 1px solid #fff;
border-radius: 12px;
background-color: #000;
transform: rotate(45deg);
position: relative;
margin-left: 14px;
margin-top: 16px;
margin-bottom: 16px;
transition: all 300ms ease-in-out;
shape-outside: circle();
}
.nav-container #main-diamond .controls-container {
position: relative;
transform: rotate(-45deg);
width: 147px;
height: 147px;
left: -22px;
top: -22px;
}
.nav-container #main-diamond .controls-container .pointer-arrow {
font-size: 8px;
position: absolute;
color: #6A696D;
transition: all 300ms ease-in-out;
}
.nav-container #main-diamond .controls-container .pointer-arrow.top {
left: 69px;
top: 13px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.top:hover {
cursor: pointer;
transform: scale(1.5);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.top:hover ~ .center-icon {
border-top-color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.right {
transform: rotate(90deg);
right: 30px;
top: 53px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.right:hover {
cursor: pointer;
transform: scale(1.5) rotate(90deg);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.right:hover ~ .center-icon {
border-right-color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.bottom {
transform: rotate(180deg);
left: 69px;
bottom: 45px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.bottom:hover {
cursor: pointer;
transform: scale(1.5) rotate(180deg);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.bottom:hover ~ .center-icon {
border-bottom-color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.left {
transform: rotate(-90deg);
left: 30px;
top: 53px;
}
.nav-container #main-diamond .controls-container .pointer-arrow.left:hover {
cursor: pointer;
transform: scale(1.5) rotate(-90deg);
color: #FFF;
}
.nav-container #main-diamond .controls-container .pointer-arrow.left:hover ~ .center-icon {
border-left-color: #FFF;
}
.nav-container #main-diamond .controls-container .center-icon {
width: 59px;
height: 59px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid #6A696D;
border-radius: 50%;
position: absolute;
left: 44px;
top: 28px;
transition: all 300ms ease-in-out;
}
.nav-container #main-diamond .controls-container .center-icon i {
font-size: 26px;
position: relative;
top: 1px;
}
.node-container {
display: block;
position: relative;
width: 342px;
height: 181px;
opacity: 1;
padding: 20px;
border-top: 1px solid #fff;
border-bottom: 1px solid #fff;
}
.node-container .node-inner-container {
position: relative;
height: 100%;
}
.node-container .node-inner-container svg.level-diamond {
position: relative;
display: inline-block;
width: 40px;
height: 40px;
float: left;
}
.node-container .node-inner-container .node-text {
width: calc(100% - 50px);
margin-left: 50px;
}
span.node-level-counter {
position: absolute;
bottom: -5px;
right: 0px;
font-weight: 200;
font-size: 12px;
}
svg.level-diamond rect.first-level {
fill: #F6AE3C;
}
svg.level-diamond text.first-level {
font-size: 20px;
font-weight: 600;
}
svg.level-diamond rect.second-level {
fill: #69C3C6;
}
svg.level-diamond text.second-level {
font-size: 18px;
font-weight: 500;
}
svg.level-diamond rect.third-level {
fill: #6DBD50;
}
svg.level-diamond text.third-level {
font-size: 16px;
font-weight: 500;
}
svg.level-diamond rect.fourth-level {
fill: #E4087D;
}
svg.level-diamond text.fourth-level {
font-size: 14px;
font-weight: 500;
}
footer {
height: 60px;
width: 100%;
display: block;
margin-top: 20px;
}
.semicircle {
position: absolute;
width: 52px;
height: 52px;
}
<script src="https://kit.fontawesome.com/a8d572acbe.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<body class="dark-mode">
<header></header>
<main>
<div class="container">
<div class="row">
<div class="col-2 p-t-180">
<div class="nav-container">
<div id="main-diamond" style="z-index: 200;">
<div class="controls-container">
<div class="pointer-arrow top" id="pointer-arrow-top"><i class="fas fa-triangle"></i></div>
<div class="pointer-arrow right" id="pointer-arrow-right"><i class="fas fa-triangle"></i></div>
<div class="pointer-arrow bottom" id="pointer-arrow-bottom"><i class="fas fa-triangle"></i></div>
<div class="pointer-arrow left" id="pointer-arrow-left"><i class="fas fa-triangle"></i></div>
<div class="center-icon">
<i class="fad fa-fingerprint"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-4 pl-1 p-t-180">
<div class="node-container" data-first data-state="active" data-node-number="1">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-1"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">1</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 1 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="2">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-2"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">2</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 2 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="3">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-3"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">3</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 3 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="4">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-4"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">4</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 4 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="5">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-5"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">5</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 5 of 6</span>
</div>
</div>
<div class="node-container" data-first data-state="inactive" data-node-number="6">
<div class="node-inner-container clearfix">
<svg viewBox="0 0 50 50" class="level-diamond" data-level="first" data-name="first" id="level-first-6"><rect x="5.95" y="5.95" width="38.1" height="38.1" rx="4.69" transform="translate(-10.36 25) rotate(-45)" class="first-level"></rect><text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" fill="#fff" class="first-level">6</text></svg>
<div class="node-text">Lorem ipsum, dolor sit amet consectetur adipisicing elit. Minus totam, repudiandae dolore.</div>
<span class="node-level-counter">Pillar 6 of 6</span>
</div>
</div>
</div>
</div>
</div>
</main>
<footer></footer>
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<script type="text/javascript" src="assets/js/app.js"></script>
</body>
从上面的示例中可以看出,当用户单击向上箭头时,第一个节点会移动到它应该到达的位置,但是节点 3 - 6 堆叠在一起,再次单击向上箭头应该会导致节点 3 出现in 集中在中间,2 位于其上方,left: -40px 和节点 1 上方,left: -80px
我无法弄清楚如何正确地做到这一点,并且已经走入了许多死胡同。
我正在使用 Vanilla javascript,因为该项目不支持 jQuery。任何帮助都会非常感谢!
【问题讨论】:
-
找不到计算函数
-
@MrKhan 感谢您提醒我删除它,因为它未使用
-
您能否逐步解释所需的行为?在第一次单击时,您希望第一个节点变为活动状态并像当前一样向上和向左移动,并且所有其他节点做什么(请描述)?在随后的点击中,您希望第二个节点做什么(请描述)而所有其他节点做什么(请描述)?真的很难猜出你的意图,从我看来你基本上有不正确的位置计算数学。
标签: javascript html css