jQuery + Bootstrap实现合法性检测和加载进度条

前言

今天在看 BootStrap 文档时,看到了进度条,但是所给的Demo都是静态的,并没有说明如何利用js控制。百度一圈也无果,大多都是自己手搓一个进度条。
但是既然 BootStrap 官方都提供进度条了,不用白不用,刚好网上相关的教程较少,难度不难,适合我这种新手博主水文章,若有不对之处还请大佬指正。
那么正文开始。

实现方法

环境

  1. BootStrap v5.3.2
  2. jQuery v3.7
  3. 一个后端用于接收请求

Servlet

由于这是个前端教程,默认有个后端用于接收和响应 POST 数据,我自己用 Servlet 写的,请自己写一个吧~(不影响下文逻辑)

HTML

我们先快速写一个 BootStrap 表单,并包含提交、进度条及一定程度的强制类型,记得引入 BootStrap 。

<body>
<div class="container">

<!-- 表单部分 不要通过这里的action提交表单 我们在js中利用 XMLHttpRequest() 方法实现-->
<form method="post" id="add" class="needs-validation">

<div class="mb-3">
<label for="fName" class="form-label">名称</label>
<!-- require 强制要求填写 maxlength 最大长度限定-->
<input type="text" class="form-control" id="fName" name="fName" maxlength="10" placeholder="一次一个" required>
<!-- 非法状态下返回值 -->
<div class="invalid-feedback">
请输入正确的名称
</div>
</div>

<div class="mb-3">
<label for="fPrice" class="form-label">单价</label>
<!-- type 强制类型为数字 -->
<input type="number" class="form-control" id="fPrice" name="fPrice" placeholder="请输入单价(罗马数字)" required>
<div class="invalid-feedback">
请输入正确的单价
</div>
</div>

<!-- 提交按钮 -->
<div class="px-4 text-center">
<div class="row gx-5">
<div class="col">
<div class="p-3"><button type="submit" class="btn btn-primary" id="submit">Submit</button></div>
</div>
</div>
</div>

<!-- 进度条部分 目前值0 最小值0 最大值100-->
<div class="progress" role="progressbar" aria-label="Animated striped example" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
<!-- 进度条内部 从0开始 -->
<div class="progress-bar progress-bar-striped progress-bar-animated" style="width: 0">0%</div>
</div>

</form>

</div>
</body>

这部分 HTML 主要实现了最基础的页面框架,基本上都是 Bootstrap 官方文档包含的内容接下来我们要实现 当点击按钮后,进度条加载,加载完成后跳转 的操作, 也就是本文的核心内容。

JavaScript

记得引入 Bootstrap 及 jQuery。

  1. 我们首先来实现合法性检测,Bootstrap 官方有个很好的案例
    平常我们写垃圾代码时更多会选择直接使用简单的 DOM 配合 if 语句判断,但这个案例很好的用到了 checkValidity() 方法,值得我们学习

    // Example starter JavaScript for disabling form submissions if there are invalid fields
    (() => {
    'use strict'

    // Fetch all the forms we want to apply custom Bootstrap validation styles to
    const forms = document.querySelectorAll('.needs-validation')

    // Loop over them and prevent submission
    Array.from(forms).forEach(form => {
    form.addEventListener('submit', event => {
    if (!form.checkValidity()) {
    event.preventDefault()
    event.stopPropagation()
    }

    form.classList.add('was-validated')
    }, false)
    })
    })()
  2. 加载进度条

    // 初始化变量
    let num = 0 // 计数器
    let p1 = $(".progress-bar") // 进度条
    // 引入 html form 参量
    let name = $("#fName")
    let price = $("#fPrice")

    // click 事件
    $("#submit").click(function () {
    if (name[0].checkValidity() && price[0].checkValidity()) {
    // 创建 XMLHttpRequest 并 初始化, 后端接口: add, POST 方法: 表格
    let xmlHttpResp = new XMLHttpRequest()
    xmlHttpResp.open("POST", "/add", true)
    xmlHttpResp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")

    // 重新格式化一下
    let params = "fName=" + name.val() + "&fPrice=" + price.val()

    // 绑定响应状态事件监听函数, 状态码正常返回 后端返回值
    xmlHttpResp.onreadystatechange = function () {
    if (xmlHttpResp.readyState === 4) {
    if (xmlHttpResp.status === 200 || xmlHttpResp.status === 0) {
    // 获取 result
    let result = xmlHttpResp.responseText

    // 定时器 根据 result 判断
    const timer = setInterval(async function () {
    p1.css("width", num + "%")
    p1.text(num + "%")
    if (num === 100) {
    if (result) {
    clearInterval(timer)
    p1.text("添加成功✅")
    await sleep(3000)
    window.location.href = "/index.html"
    } else {
    clearInterval(timer)
    p1.text("添加失败😭")
    }
    }
    num++
    }, 10);
    }
    }
    }
    // 提交 POST
    xmlHttpResp.send(params)

    } else {
    // 记录异常
    console.log('可能存在的,未知 参数 错误')
    }
    })

    // sleep
    function sleep(delay) {
    return new Promise(resolve => {
    setTimeout(resolve, delay)
    })
    }

    这一步利用 XMLHttpRequest() 方法实现了 POST 的同时,让后端返回一个返回值,利用返回值判断是否成功。
    之后利用 setInterval() 方法做计时器使得进度条累加(伪进度条,只是个动画效果),根据 result 返回来的值来确认是否成功提交。最后设置一个 sleep, 让线程睡眠 3 秒,实现等待的效果,为了防止阻塞,故用到了 async, 以上就是 Bootstrap 进度条的简单应用。

TroubShooting

  1. DOM 的 document.getElementById("id") 和 jQuery 的 $("#id") 是有区别的

    在网上查找资料时,看到一种说法是这两个方法是一样的,但其实,前者获取到的是元素 ,而 后者获取到的是HTMLCollection

    后者(即jQuery)获取元素及值的方法如下:

    let id =  $("#id")

    //获取元素
    console.log(id[0])

    //获取值
    console.log(id.val())

结语

写这篇文章的初衷是因为网上 度娘 的教程很多内容是错的,而且出现了大量文章都出自同一个作者,一人错处处错,让我看得特别难受,虽然内容都是基础内容,但这也大大增高了新同学的学习门槛。但同时我也深知我的文章写的不够优秀,只希望倘若能有一位同学看懂了,少走些弯路,也不乏是件好事,但若是我有出错之处,还请在评论区指正。这是我第一次写这类博客,希望我自己未来在精进代码能力的同时,也不断提高博客写作水平,以带给大家更好的内容为基准点,不断向更高处前进。

感谢每一位读完这篇博文的朋友们,这是我这个域名认真写的第一篇技术类文章,即是我上一段旅途的重点,亦是我这一段行程的起点,是每一个阅读量促使着我一步步走到现在,衷心地感谢你们,最后,用我最喜欢的一句话,我的座右铭,祝愿大家,Le vent se lève, il faut tenter de vivre(纵使疾风起,人生不言弃)

参考文献