HTMLとCSSでタイムラインを作成しました。JavaScriptでタイムラインステップを制御するためのボタンを作成したいと思います。
タイムラインはいくつかのステップで構成されています。各ステップには3つの状態があります。
1)通常 .timeline__step
2)合格 .timeline__step--passed
3)アクティブ .timeline__step--active
「前へ」と「次へ」の2つのボタンを実行したい。セレクターでノードを見つけることができます。でも、ステップを無限に切り替えることができるコードの書き方がわかりません。
HTML:
<div class="timeline" id="timeline1">
<div class="timeline__step timeline__step--passed">
<span class="timeline__label">Step 1</span>
</div>
<div class="timeline__step timeline__step--passed">
<span class="timeline__label">Step 2</span>
</div>
<div class="timeline__step timeline__step--active">
<span class="timeline__label">Step 3</span>
</div>
<div class="timeline__step">
<span class="timeline__label">Step 4</span>
</div>
</div>
codepenのタイムラインフルバージョン:https://codepen.io/vlad3k-the-sasster/pen/rNNpBMb
Next
ボタンを実装するには、ボタンをクリックするたびに実行する必要があります。
timeline__step--active
要素を見つけて、その要素からクラスを削除しますclassList
timeline__step--active
Prev
ボタンは似ていますが、他の方法で回避しています。
簡単な例(私もサンプルコーデックを作成しました):
const timeline = document.getElementById('timeline1');
const btnChangeStyle = document.getElementById('toggle-style');
const btnChangeLabelPos = document.getElementById('toggle-label-pos');
const steps = timeline.querySelectorAll('.timeline__step');
function changeStyle() {
timeline.classList.toggle('timeline--points');
}
function changeLabelsPosition() {
timeline.classList.toggle('timeline--labels-underline');
}
btnChangeStyle.addEventListener('click', changeStyle);
btnChangeLabelPos.addEventListener('click', changeLabelsPosition);
document.querySelector('#next').addEventListener('click', () => {
let steps = document.querySelectorAll("#timeline1 > .timeline__step");
let passedSteps = document.querySelectorAll("#timeline1 > .timeline__step--passed");
let firstStep = document.querySelector("#timeline1 > .timeline__step:first-child");
let activeStep = document.querySelector("#timeline1 > .timeline__step--active");
let nextStep;
if(steps.length == passedSteps.length) {
return;
}
if(activeStep) {
activeStep.classList.remove('timeline__step--active');
activeStep.classList.add('timeline__step--passed');
nextStep = activeStep.nextElementSibling
}
if(nextStep) {
nextStep.classList.add('timeline__step--active');
} else if(passedSteps.length === 0) {
firstStep.classList.add('timeline__step--active');
}
});
document.querySelector('#prev').addEventListener('click', () => {
let passedSteps = document.querySelectorAll("#timeline1 > .timeline__step--passed");
let lastStep = document.querySelector("#timeline1 > .timeline__step:last-child");
let activeStep = document.querySelector("#timeline1 > .timeline__step--active");
let prevStep;
if(passedSteps.length === 0) {
return;
}
if(activeStep) {
activeStep.classList.remove('timeline__step--active');
activeStep.classList.remove('timeline__step--passed');
prevStep = activeStep.previousElementSibling;
}
if(prevStep) {
prevStep.classList.add('timeline__step--active');
} else if(passedSteps.length === steps.length) {
lastStep.classList.remove('timeline__step--passed');
lastStep.classList.add('timeline__step--active');
}
});
body {
margin-top: 50px;
}
/* Timeline */
.timeline {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 30px;
margin-bottom: 50px; /* optional property */
}
.timeline__step {
position: relative;
text-align: center;
flex-grow: 1;
height: 2px;
background-color: lightgrey;
}
.timeline__step::before,
.timeline__step:last-child::after {
content: "";
position: absolute;
top: 50%;
left: 0;
display: block;
height: 11px;
width: 11px;
background-color: #ffffff;
border: 2px solid lightgray;
border-radius: 50%;
box-sizing: border-box;
box-shadow: 0 0 0 2px #fff;
transform: translate(-50%, -50%);
}
.timeline__step:first-child::before {
transform: translate(0%, -50%);
}
.timeline__step:last-child::after {
left: auto;
right: 0;
transform: translate(0%, -50%);
}
.timeline__label {
position: absolute;
left: 50%;
bottom: 10px;
transform: translateX(-50%);
}
.timeline__step--passed,
.timeline__step--passed::before,
.timeline__step--passed:last-child::after {
background-color: green;
border-color: green;
}
.timeline__step--active,
.timeline__step--active::before {
background-color: orange;
border-color: orange;
}
/* Timeline points style (SASS Syntax) */
.timeline--points {
.timeline__step:first-child {
.timeline__label {
transform: translateX(0);
}
}
.timeline__step:last-child {
position: absolute;
right: 0;
width: 100%;
background: none;
&::before {
left: auto;
right: 0;
transform: translate(0, -50%);
}
&::after {
display: none;
}
.timeline__label {
left: auto;
right: 0;
transform: translateX(0);
}
}
.timeline__label {
position: absolute;
left: 0;
transform: translateX(-50%);
}
.timeline__step--active {
background: lightgray;
}
}
/* Timeline label position (SASS Syntax) */
.timeline--labels-underline {
.timeline__label {
bottom: auto;
top: 10px;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<title>Document</title>
</head>
<body>
<div class="container">
<div class="timeline" id="timeline1">
<div class="timeline__step timeline__step--passed">
<span class="timeline__label">Step 1</span>
</div>
<div class="timeline__step timeline__step--passed">
<span class="timeline__label">Step 2</span>
</div>
<div class="timeline__step timeline__step--active">
<span class="timeline__label">Step 3</span>
</div>
<div class="timeline__step">
<span class="timeline__label">Step 4</span>
</div>
<div class="timeline__step">
<span class="timeline__label">Step 5</span>
</div>
</div>
<button id="toggle-style" type="button" class="btn btn-outline-primary">Toggle style</button>
<button id="toggle-label-pos" type="button" class="btn btn-outline-primary">Toggle label position</button>
<button id="prev" class="btn btn-primary">< Prev</button>
<button id="next" class="btn btn-primary">Next ></button>
</div>
</body>
</html>
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加