Jquery完成一个多层的进度条,如何实现?

<link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.0/css/bootstrap.min.css">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <div class="stepsBox">
            <ul class="list-unstyled">
              <li class="stepBar alert alert-light">
                <div class="stepTitle">步骤一</div>
                <div class="stepContent">
                  <ol>
                    <li>
                      <div class="row">
                        <div class="col-md-8 text-left">
                          <div class="stepContentTitle">1.1 标题</div>
                        </div>
                        <div class="col-md-4 text-right">
                          <div class="stepFinishTime">
                            2024年8月1日 13:17:00
                          </div>
                        </div>
                      </div>
                      <div class="stepContentText">
                        Lorem
                      </div>
                    </li>
                    <li>
                      <div class="row">
                        <div class="col-md-8 text-left">
                          <div class="stepContentTitle">1.2 标题</div>
                        </div>
                        <div class="col-md-4 text-right">
                          <div class="stepFinishTime">
                            2024年8月1日 13:17:00
                          </div>
                        </div>
                      </div>
                      <div class="stepContentText">
                        Lorem
                      </div>
                    </li>
                    <li>
                      <div class="row">
                        <div class="col-md-8 text-left">
                          <div class="stepContentTitle">1.3标题</div>
                        </div>
                        <div class="col-md-4 text-right">
                          <div class="stepFinishTime">
                            2024年8月1日 13:17:00
                          </div>
                        </div>
                      </div>
                      <div class="stepContentText">
                        Lorem
                      </div>
                    </li>
                  </ol>
                </div>
              </li>
              <li class="stepBar alert alert-secondary">
                <div class="stepTitle">步骤二</div>
                <div class="stepContent">
                  <ol>
                    <li>
                      <div class="row">
                        <div class="col-md-8 text-left">
                          <div class="stepContentTitle">2.1标题</div>
                        </div>
                        <div class="col-md-4 text-right">
                          <div class="stepFinishTime">
                            2024年8月1日 13:17:00
                          </div>
                        </div>
                      </div>
                      <div class="stepContentText">
                        Lorem
                      </div>
                    </li>
                    <li>
                      <div class="row">
                        <div class="col-md-8 text-left">
                          <div class="stepContentTitle">2.1标题</div>
                        </div>
                        <div class="col-md-4 text-right">
                          <div class="stepFinishTime">
                            2024年8月1日 13:17:00
                          </div>
                        </div>
                      </div>
                      <div class="stepContentText">
                        Lorem
                      </div>
                    </li>
                  </ol>
                </div>
              </li>
              <li class="stepBar alert alert-secondary">
                <div class="stepTitle">步骤三</div>
                <div class="stepContent">
                  <ol>
                    <li>
                      <div class="row">
                        <div class="col-md-8 text-left">
                          <div class="stepContentTitle">3.1标题</div>
                        </div>
                        <div class="col-md-4 text-right">
                          <div class="stepFinishTime">
                            2024年8月1日 13:17:00
                          </div>
                        </div>
                      </div>
                      <div class="stepContentText">
                        Lorem
                      </div>
                    </li>
                    <li>
                      <div class="row">
                        <div class="col-md-8 text-left">
                          <div class="stepContentTitle">3.2标题</div>
                        </div>
                        <div class="col-md-4 text-right">
                          <div class="stepFinishTime">
                            2024年8月1日 13:17:00
                          </div>
                        </div>
                      </div>
                      <div class="stepContentText">
                        Lorem
                      </div>
                    </li>
                    <li>
                      <div class="row">
                        <div class="col-md-8 text-left">
                          <div class="stepContentTitle">3.3标题</div>
                        </div>
                        <div class="col-md-4 text-right">
                          <div class="stepFinishTime">
                            2024年8月1日 13:17:00
                          </div>
                        </div>
                      </div>
                      <div class="stepContentText">
                        Lorem
                      </div>
                    </li>
                    <li>
                      <div class="row">
                        <div class="col-md-8 text-left">
                          <div class="stepContentTitle">3.4标题</div>
                        </div>
                        <div class="col-md-4 text-right">
                          <div class="stepFinishTime">
                            2024年8月1日 13:17:00
                          </div>
                        </div>
                      </div>
                      <div class="stepContentText">
                        Lorem
                      </div>
                    </li>
                  </ol>
                </div>
              </li>
            </ul>
            <div class="btnBox d-flex justify-content-between">
              <button
                type="button"
                class="btn btn-secondary previousBtn"
                disabled
              >
                上一步
              </button>
              <button type="button" class="btn btn-primary nextBtn">
                下一步
              </button>
            </div>
            <div class="progressBar"></div>
          </div>
$(document).ready(function () {
    $('.stepsBox .stepBar').eq(0).find('.stepContent > ol > li').eq(0).addClass('activeBox');

    $('.nextBtn').on('click', function () {
        var currentStep = $('.stepsBox .stepBar').find('.activeBox');
        var nextStep = currentStep.next();


        if (nextStep.length) {
            $('.stepsBox .stepContent ol li').each(function () {
                $(this).removeClass('activeBox');
            });
            debugger
            nextStep.addClass('activeBox');
            var currentStepBar = currentStep.closest('.stepBar');
            var nextStepBar = currentStepBar.next('.stepBar');
            var currentStepIndex = currentStep.index();
            var nextStepBarLength = nextStepBar.find('.stepContent > ol > li').length;

            if (currentStepIndex === nextStepBarLength - 1 && nextStepBar.length) {

                currentStepBar.removeClass('alert-light').addClass('alert-secondary');
                nextStepBar.removeClass('alert-secondary').addClass('alert-light');
                nextStepBar.find('.stepContent > ol > li').eq(0).addClass('activeBox');


                if (!nextStepBar.next('.stepBar').length) {
                    $(this).removeClass('btn-primary').addClass('btn-secondary').attr('disabled', 'disabled');
                }
            }
        } else {
            $(this).removeClass('btn-primary').addClass('btn-secondary').attr('disabled', 'disabled');
        }
    });
});

默认给第一个stepBar添加activeBox,点击下一步li增加CSS activeBox,移除上一个;
如果下一个stepBar增加CSS alert alert-light,移除上一个并增加CSS alert alert-secondary;
如果是最后一个li 点击下一步Btn 增加btn-secondary disabled,上一步同理。

写了一半,越来越乱,求点思路,谢谢。

阅读 2.3k
avatarAI BotBETA

要实现一个多层的进度条,并结合你当前的HTML结构和jQuery代码,我们可以进行一些修改和添加。以下是一个简化和完善的示例,包括进度条的实现和按钮逻辑的完善。

HTML 结构(保持不变)

你的HTML结构已经很好地支持了多层步骤和子步骤的展示,这里我们主要关注进度条的实现和按钮逻辑的完善。

CSS 添加(可选)

为了更清晰地展示进度条,我们可以添加一些简单的CSS。这里我们使用了一个简单的进度条样式,你可以根据需要进行调整。

.progressBar {
    height: 20px;
    background-color: #ddd;
    margin-top: 20px;
}

.progressBar .progress {
    height: 100%;
    background-color: #4CAF50;
    width: 0%; /* 初始宽度为0% */
    transition: width 0.4s ease-in-out;
}

jQuery 代码修改

我们需要更新jQuery代码,以便在点击下一步时更新进度条,并处理上一步的逻辑。

$(document).ready(function () {
    var activeStep = 0; // 当前活动的步骤索引
    var totalSteps = $('.stepsBox .stepBar').length; // 总步骤数
    var progressBar = $('.progressBar').append('<div class="progress"></div>'); // 创建进度条

    // 初始化第一个步骤为活动状态
    $('.stepsBox .stepBar').eq(activeStep).addClass('activeStep');
    $('.stepsBox .stepBar .stepContent > ol > li').eq(0).addClass('activeBox');

    // 更新进度条
    function updateProgressBar() {
        var progressWidth = (activeStep + 1) / totalSteps * 100;
        $('.progressBar .progress').css('width', progressWidth + '%');
    }

    // 点击下一步
    $('.nextBtn').on('click', function () {
        var currentStepBar = $('.stepsBox .stepBar').eq(activeStep);
        var currentActiveLi = currentStepBar.find('.activeBox');
        var nextLi = currentActiveLi.next();

        if (nextLi.length) {
            currentActiveLi.removeClass('activeBox');
            nextLi.addClass('activeBox');
        } else {
            // 当前步骤的所有子步骤已完成,移动到下一个步骤
            activeStep++;
            $('.stepsBox .stepBar').removeClass('activeStep').eq(activeStep).addClass('activeStep');
            $('.stepsBox .stepBar .stepContent > ol > li').eq(0).addClass('activeBox');

            // 切换步骤条的颜色
            $('.stepsBox .stepBar').eq(activeStep - 1).removeClass('alert-light').addClass('alert-secondary');
            $('.stepsBox .stepBar').eq(activeStep).removeClass('alert-secondary').addClass('alert-light');

            // 检查是否到达最后一个步骤
            if (activeStep === totalSteps - 1) {
                $(this).prop('disabled', true).removeClass('btn-primary').addClass('btn-secondary');
            }

            // 更新进度条
            updateProgressBar();
        }
    });

    // 点击上一步(可选实现)
    $('.previousBtn').on('click', function () {
        if (activeStep > 0) {
            activeStep--;
            $('.stepsBox .stepBar').removeClass('activeStep').eq(activeStep).addClass('activeStep');

            // 激活上一步骤的最后一个完成的子步骤(这里简化处理,总是回到第一个子步骤)
            $('.stepsBox .stepBar').eq(activeStep).find('.stepContent > ol > li').eq(0).addClass('activeBox');

            // 切换步骤条的颜色
            $('.stepsBox .stepBar').eq(activeStep + 1).removeClass('alert-light').addClass('alert-secondary');
            $('.stepsBox .stepBar').eq(activeStep).removeClass('alert-secondary').addClass('alert-light');

            // 启用下一步按钮
            $('.nextBtn').prop('disabled', false).removeClass('btn-secondary').addClass('btn-primary');

            // 更新进度条
            updateProgressBar();
        }
    });

    // 初始进度条
    updateProgressBar();
});

这段代码包括了进度条的初始化、更新,以及上下一步按钮的逻辑处理。你可以根据自己的需求调整样式和行为。

2 个回答
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="Content-Type: text/html; charset=UTF-8">
  <title>多层次进度条示例</title>
  <link rel="stylesheet" href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.0/css/bootstrap.min.css">
  <style>
    .activeBox {
      background-color: #d1e7dd !important; /* 背景色 */
    }
    .progressBar {
      margin-top: 20px;
    }
    .stepBar {
      margin-bottom: 20px;
    }
    .stepTitle {
      font-weight: bold;
      font-size: 1.2em;
      margin-bottom: 10px;
    }
    .stepContent ol {
      padding-left: 20px;
    }
    .stepContentTitle {
      font-weight: 500;
    }
    .btnBox {
      margin-top: 20px;
    }
    .progress-bar {
      transition: width 0.6s ease;
    }
  </style>
</head>
<body>
  <div class="container my-5">
    <div class="stepsBox">
      <ul class="list-unstyled">
        <li class="stepBar alert alert-light" data-step="1">
          <div class="stepTitle">步骤一</div>
          <div class="stepContent">
            <ol>
              <li data-substep="1">
                <div class="row">
                  <div class="col-md-8 text-left">
                    <div class="stepContentTitle">1.1 标题</div>
                  </div>
                  <div class="col-md-4 text-right">
                    <div class="stepFinishTime">
                      2024年8月1日 13:17:00
                    </div>
                  </div>
                </div>
                <div class="stepContentText">
                  Lorem ipsum dolor sit amet.
                </div>
              </li>
              <li data-substep="2">
                <div class="row">
                  <div class="col-md-8 text-left">
                    <div class="stepContentTitle">1.2 标题</div>
                  </div>
                  <div class="col-md-4 text-right">
                    <div class="stepFinishTime">
                      2024年8月1日 13:17:00
                    </div>
                  </div>
                </div>
                <div class="stepContentText">
                  Consectetur adipiscing elit.
                </div>
              </li>
              <li data-substep="3">
                <div class="row">
                  <div class="col-md-8 text-left">
                    <div class="stepContentTitle">1.3 标题</div>
                  </div>
                  <div class="col-md-4 text-right">
                    <div class="stepFinishTime">
                      2024年8月1日 13:17:00
                    </div>
                  </div>
                </div>
                <div class="stepContentText">
                  Sed do eiusmod tempor incididunt.
                </div>
              </li>
            </ol>
          </div>
        </li>
        <li class="stepBar alert alert-secondary" data-step="2">
          <div class="stepTitle">步骤二</div>
          <div class="stepContent">
            <ol>
              <li data-substep="1">
                <div class="row">
                  <div class="col-md-8 text-left">
                    <div class="stepContentTitle">2.1 标题</div>
                  </div>
                  <div class="col-md-4 text-right">
                    <div class="stepFinishTime">
                      2024年8月1日 13:17:00
                    </div>
                  </div>
                </div>
                <div class="stepContentText">
                  Ut labore et dolore magna aliqua.
                </div>
              </li>
              <li data-substep="2">
                <div class="row">
                  <div class="col-md-8 text-left">
                    <div class="stepContentTitle">2.2 标题</div>
                  </div>
                  <div class="col-md-4 text-right">
                    <div class="stepFinishTime">
                      2024年8月1日 13:17:00
                    </div>
                  </div>
                </div>
                <div class="stepContentText">
                  Ut enim ad minim veniam.
                </div>
              </li>
            </ol>
          </div>
        </li>
        <li class="stepBar alert alert-secondary" data-step="3">
          <div class="stepTitle">步骤三</div>
          <div class="stepContent">
            <ol>
              <li data-substep="1">
                <div class="row">
                  <div class="col-md-8 text-left">
                    <div class="stepContentTitle">3.1 标题</div>
                  </div>
                  <div class="col-md-4 text-right">
                    <div class="stepFinishTime">
                      2024年8月1日 13:17:00
                    </div>
                  </div>
                </div>
                <div class="stepContentText">
                  Duis aute irure dolor in reprehenderit.
                </div>
              </li>
              <li data-substep="2">
                <div class="row">
                  <div class="col-md-8 text-left">
                    <div class="stepContentTitle">3.2 标题</div>
                  </div>
                  <div class="col-md-4 text-right">
                    <div class="stepFinishTime">
                      2024年8月1日 13:17:00
                    </div>
                  </div>
                </div>
                <div class="stepContentText">
                  In voluptate velit esse cillum dolore.
                </div>
              </li>
              <li data-substep="3">
                <div class="row">
                  <div class="col-md-8 text-left">
                    <div class="stepContentTitle">3.3 标题</div>
                  </div>
                  <div class="col-md-4 text-right">
                    <div class="stepFinishTime">
                      2024年8月1日 13:17:00
                    </div>
                  </div>
                </div>
                <div class="stepContentText">
                  Eu fugiat nulla pariatur.
                </div>
              </li>
              <li data-substep="4">
                <div class="row">
                  <div class="col-md-8 text-left">
                    <div class="stepContentTitle">3.4 标题</div>
                  </div>
                  <div class="col-md-4 text-right">
                    <div class="stepFinishTime">
                      2024年8月1日 13:17:00
                    </div>
                  </div>
                </div>
                <div class="stepContentText">
                  Excepteur sint occaecat cupidatat non proident.
                </div>
              </li>
            </ol>
          </div>
        </li>
      </ul>
      <div class="btnBox d-flex justify-content-between">
        <button type="button" class="btn btn-secondary previousBtn" disabled>
          上一步
        </button>
        <button type="button" class="btn btn-primary nextBtn">
          下一步
        </button>
      </div>
      <div class="progressBar">
        <div class="progress">
          <div class="progress-bar" role="progressbar" style="width: 0%;" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
        </div>
      </div>
    </div>

    <!-- 引入jQuery -->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <!-- 引入Bootstrap JS -->
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.0/js/bootstrap.bundle.min.js"></script>
    <script>
      $(document).ready(function () {
        // 初始化:激活第一个步骤的第一个子步骤
        $('.stepsBox .stepBar').removeClass('alert-light alert-secondary');
        $('.stepsBox .stepBar').first().addClass('alert-light');
        $('.stepsBox .stepBar').first().find('.stepContent > ol > li').first().addClass('activeBox');

        // 计算总步骤和总子步骤
        var totalSteps = $('.stepsBox .stepBar').length;
        var currentStep = 1;
        var currentSubStep = 1;

        // 计算总子步骤
        var totalSubSteps = 0;
        $('.stepsBox .stepBar').each(function () {
          totalSubSteps += $(this).find('.stepContent > ol > li').length;
        });

        var completedSubSteps = 1; // 初始已完成的子步骤

        // 更新进度条
        function updateProgressBar() {
          var progressPercentage = (completedSubSteps / totalSubSteps) * 100;
          $('.progress-bar').css('width', progressPercentage + '%').attr('aria-valuenow', progressPercentage);
        }

        updateProgressBar();

        // 点击“下一步”按钮
        $('.nextBtn').on('click', function () {
          var currentStepBar = $('.stepsBox .stepBar[data-step="' + currentStep + '"]');
          var currentLi = currentStepBar.find('.stepContent > ol > li[data-substep="' + currentSubStep + '"]');

          // 移除当前activeBox
          currentLi.removeClass('activeBox');

          // 判断是否还有下一个子步骤
          var nextSubStep = currentSubStep + 1;
          var totalCurrentSubSteps = currentStepBar.find('.stepContent > ol > li').length;

          if (nextSubStep > totalCurrentSubSteps) {
            // 如果当前步骤的子步骤已全部完成,移动到下一个步骤
            currentStepBar.removeClass('alert-light').addClass('alert-secondary');
            currentStep += 1;

            if (currentStep > totalSteps) {
              // 如果已经是最后一个步骤,禁用“下一步”按钮
              $('.nextBtn').removeClass('btn-primary').addClass('btn-secondary').attr('disabled', 'disabled');
              return;
            }

            var nextStepBar = $('.stepsBox .stepBar[data-step="' + currentStep + '"]');
            nextStepBar.removeClass('alert-secondary').addClass('alert-light');
            currentSubStep = 1;
            nextStepBar.find('.stepContent > ol > li[data-substep="' + currentSubStep + '"]').addClass('activeBox');
          } else {
            // 否则,移动到下一个子步骤
            currentSubStep = nextSubStep;
            currentStepBar.find('.stepContent > ol > li[data-substep="' + currentSubStep + '"]').addClass('activeBox');
          }

          // 增加已完成的子步骤
          completedSubSteps += 1;
          updateProgressBar();

          // 启用“上一步”按钮
          $('.previousBtn').removeAttr('disabled');
        });

        // 点击“上一步”按钮
        $('.previousBtn').on('click', function () {
        
          if (currentSubStep === 1) {
           
            var currentStepBar = $('.stepsBox .stepBar[data-step="' + currentStep + '"]');
            currentStepBar.removeClass('alert-light').addClass('alert-secondary');
            currentStep -= 1;

            if (currentStep < 1) {
              // 如果已经是第一个步骤,禁用“上一步”按钮
              $('.previousBtn').attr('disabled', 'disabled');
              return;
            }

            var prevStepBar = $('.stepsBox .stepBar[data-step="' + currentStep + '"]');
            prevStepBar.removeClass('alert-secondary').addClass('alert-light');
            var totalPrevSubSteps = prevStepBar.find('.stepContent > ol > li').length;
            currentSubStep = totalPrevSubSteps;
            prevStepBar.find('.stepContent > ol > li[data-substep="' + currentSubStep + '"]').addClass('activeBox');
          } else {
            // 否则,移动到上一个子步骤
            var currentStepBar = $('.stepsBox .stepBar[data-step="' + currentStep + '"]');
            currentStepBar.find('.stepContent > ol > li[data-substep="' + currentSubStep + '"]').removeClass('activeBox');
            currentSubStep -= 1;
            currentStepBar.find('.stepContent > ol > li[data-substep="' + currentSubStep + '"]').addClass('activeBox');
          }

          completedSubSteps -= 1;
          updateProgressBar();

          $('.nextBtn').removeClass('btn-secondary').addClass('btn-primary').removeAttr('disabled');
        });
      });
    </script>
  </div>
</body>
</html>

效果图:
image.png
image.png
image.png
image.png

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏