Skip to content
001

02_Bootstrap 弹框 + 图片上传

01_Bootstrap 弹框

01_属性控制显示隐藏

01_属性控制显示隐藏

功能: 不离开当前页面, 显示单独内容, 供用户操作

步骤:

  1. 引入 bootstrap.css 和 bootstrap.js
  2. 准备 弹框标签, 确认结构
  3. 通过 自定义属性, 控制弹框的 显示隐藏
002
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  
  <!-- 1.引入 bootstrap.css -->
  <link href="./Bootstrap/Bootstrap5.2.2.css" rel="stylesheet">
</head>

<body>
  <!-- 4.通过自定义属性, 控制弹框的显示和隐藏, 显示弹框: data-bs-toggle="modal" data-bs-target="css 选择器" -->
  <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target=".my-box">
    显示弹框
  </button>

  <!-- 3.弹框标签: bootstrap 的 modal 弹框, 添加 modal 类名 (默认隐藏)  -->
  <div class="modal my-box" tabindex="-1">
    <div class="modal-dialog">
      <!-- 弹框-内容 -->
      <div class="modal-content">
        <!-- 弹框-头部 -->
        <div class="modal-header">
          <h5 class="modal-title">Modal title</h5>
          <!-- 5.关闭弹框: data-bs-dismiss="modal" -->
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>

        <!-- 弹框-身体 -->
        <div class="modal-body">
          <p>Modal body text goes here.</p>
        </div>

        <!-- 弹框-底部 -->
        <div class="modal-footer">
          <!-- 6.关闭弹框: data-bs-dismiss="modal" -->
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
          <button type="button" class="btn btn-primary">Save changes</button>
        </div>
      </div>
    </div>
  </div>

  <!-- 2.引入 bootstrap.js -->
  <script src="./Bootstrap/Bootstrap 5.2.2.js"></script>
</body>

</html>

02_JS 控制显示隐藏

01_JS 控制显示隐藏

  1. 通过属性控制, 弹框显示或隐藏 单纯显示/隐藏
  2. 通过 JS 控制, 弹框显示或隐藏 额外逻辑代码
003
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <!-- 引入 bootstrap.css -->
  <link href="./Bootstrap/Bootstrap5.2.2.css" rel="stylesheet">
</head>

<body>
  <button type="button" class="btn btn-primary edit-btn">
    编辑姓名
  </button>

  <!-- 弹框标签 -->
  <div class="modal name-box" tabindex="-1">
    <div class="modal-dialog">
      <!-- 弹框-内容 -->
      <div class="modal-content">
        <!-- 弹框-头部 -->
        <div class="modal-header">
          <h5 class="modal-title">请输入姓名</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <!-- 弹框-身体 -->
        <div class="modal-body">
          <form action="">
            <span>姓名: </span>
            <input type="text" class="username">
          </form>
        </div>
        <!-- 弹框-底部 -->
        <div class="modal-footer">
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
          <button type="button" class="btn btn-primary save-btn">保存</button>
        </div>
      </div>
    </div>
  </div>

  <!-- 引入 bootstrap.js -->
  <script src="./Bootstrap/Bootstrap 5.2.2.js"></script>

  <script>
    // 1.创建弹框对象
    const modalDom = document.querySelector('.name-box')
    const modal = new bootstrap.Modal(modalDom)

    // 2.编辑姓名 ==> 点击 ==> 赋予默认姓名 ==> 弹框显示
    document.querySelector('.edit-btn').addEventListener('click', () => {
      document.querySelector('.username').value = '默认姓名'

      // 3.显示弹框
      modal.show()
    })

    // 4.保存 ==> 点击 ==> 获取姓名打印 ==> 弹框隐藏
    document.querySelector('.save-btn').addEventListener('click', () => {
      const username = document.querySelector('.username').value
      console.log('模拟把姓名保存到服务器上', username)

      // 5.隐藏弹框
      modal.hide()
    })
  </script>
</body>

</html>

02_图书管理

01_渲染列表

01_渲染列表

自己的图书数据: 给自己起个 外号, 并告诉服务器, 默认会有三本书, 基于这三本书做数据的 增删改查

004
javascript
// /code/js/index.js

const creator = '老张'

// 1.封装 获取并渲染图书列表函数
function getBooksList() {
  // 3.获取数据
  axios({
    url: 'http://hmajax.itheima.net/api/books',
    params: {
      creator // 外号: 获取对应数据
    }
  }).then(result => {
    const bookList = result.data.data

    // 4.渲染数据
    const htmlStr = bookList.map((item, index) => {
      return `<tr>
      <td>${index + 1}</td>
      <td>${item.bookname}</td>
      <td>${item.author}</td>
      <td>${item.publisher}</td>
      <td data-id=${item.id}>
        <span class="del">删除</span>
        <span class="edit">编辑</span>
      </td>
    </tr>`
    }).join('')
    document.querySelector('.list').innerHTML = htmlStr
  })
}

// 2.网页加载运行, 获取并渲染列表一次
getBooksList()

02_新增图书

01_新增图书

005
javascript
// /code/js/index.js

// 1.创建弹框对象
const addModalDom = document.querySelector('.add-modal')
const addModal = new bootstrap.Modal(addModalDom)

// 2.保存按钮 ==> 点击 ==> 隐藏弹框
document.querySelector('.add-btn').addEventListener('click', () => {
  // 3.收集表单数据, 并提交到服务器保存
  const addForm = document.querySelector('.add-form')
  const bookObj = serialize(addForm, { hash: true, empty: true })

  // 4.提交到服务器
  axios({
    url: 'http://hmajax.itheima.net/api/books',
    method: 'POST',
    data: {
      ...bookObj,
      creator
    }
  }).then(result => {
    // 5.添加成功后, 重新请求并渲染图书列表
    getBooksList()
    
    addForm.reset() // 重置表单
    addModal.hide() // 隐藏弹框
  })
})

03_删除图书

01_删除图书

006
javascript
// /code/js/index.js

// 1.删除元素 ==> 点击 (事件委托) 
document.querySelector('.list').addEventListener('click', e => {
  // 2.获取触发事件目标元素
  // console.log(e.target)

  // 3.判断点击的是删除元素
  if (e.target.classList.contains('del')) {
    // 4.获取图书 id (自定义属性 id) 
    const theId = e.target.parentNode.dataset.id

    // 5.调用删除接口
    axios({
      url: `http://hmajax.itheima.net/api/books/${theId}`,
      method: 'DELETE'
    }).then(() => {
      // 6.刷新图书列表
      getBooksList()
    })
  }
})

04_编辑图书 弾框准备

01_编辑图书 弾框准备

007
javascript
// /code/js/index.js

// 1.编辑弹框 ==> 显示和隐藏
const editDom = document.querySelector('.edit-modal')
const editModal = new bootstrap.Modal(editDom)

// 2.编辑元素 ==> 点击 ==> 弹框显示
document.querySelector('.list').addEventListener('click', e => {
  // 3.判断点击的是否为编辑元素
  if (e.target.classList.contains('edit')) {
    editModal.show() // 显示弹框
  }
})

// 4.修改按钮 ==> 点击 ==> 隐藏弹框
document.querySelector('.edit-btn').addEventListener('click', () => {
  editModal.hide() // 隐藏弹框
})

05_编辑图书 数据回显

01_编辑图书 数据回显

008
javascript
// /code/js/index.js

// 编辑弹框 ==> 显示和隐藏
const editDom = document.querySelector('.edit-modal')
const editModal = new bootstrap.Modal(editDom)

// 编辑元素 ==> 点击 ==> 弹框显示
document.querySelector('.list').addEventListener('click', e => {
  // 判断点击的是否为编辑元素
  if (e.target.classList.contains('edit')) {
    // 1.获取当前编辑图书数据 ==> 回显到编辑表单中
    const theId = e.target.parentNode.dataset.id
    axios({
      url: `http://hmajax.itheima.net/api/books/${theId}`
    }).then(result => {
      const bookObj = result.data.data

      // 2.数据对象 "属性" 和标签 "类名" 一致; 遍历数据对象, 使用属性去获取对应的标签, 快速赋值
      const keys = Object.keys(bookObj) // ['id', 'bookname', 'author', 'publisher']
      keys.forEach(key => {
        document.querySelector(`.edit-form .${key}`).value = bookObj[key]
      })
    })
    
    editModal.show() // 显示弹框
  }
})

// 修改按钮 ==> 点击 ==> 隐藏弹框
document.querySelector('.edit-btn').addEventListener('click', () => {
  editModal.hide() // 隐藏弹框
})

06_编辑图书 保存修收

01_编辑图书 保存修收

009
javascript
// /code/js/index.js

// 编辑弹框 ==> 显示和隐藏
const editDom = document.querySelector('.edit-modal')
const editModal = new bootstrap.Modal(editDom)

// 编辑元素 ==> 点击 ==> 弹框显示
document.querySelector('.list').addEventListener('click', e => {
  // 判断点击的是否为编辑元素
  if (e.target.classList.contains('edit')) {
    // 获取当前编辑图书数据 ==> 回显到编辑表单中
    const theId = e.target.parentNode.dataset.id
    axios({
      url: `http://hmajax.itheima.net/api/books/${theId}`
    }).then(result => {
      const bookObj = result.data.data

      // 数据对象 "属性" 和标签 "类名" 一致; 遍历数据对象, 使用属性去获取对应的标签, 快速赋值
      const keys = Object.keys(bookObj) // ['id', 'bookname', 'author', 'publisher']
      keys.forEach(key => {
        document.querySelector(`.edit-form .${key}`).value = bookObj[key]
      })
    })
    
    editModal.show() // 显示弹框
  }
})

// 修改按钮 ==> 点击 ==> 隐藏弹框
document.querySelector('.edit-btn').addEventListener('click', () => {
  // 1.提交保存修改, 并刷新列表
  const editForm = document.querySelector('.edit-form')
  const { id, bookname, author, publisher } = serialize(editForm, { hash: true, empty: true})

  // 2.保存正在编辑的图书 id, 隐藏起来: 无需让用户修改
  // <input type="hidden" class="id" name="id" value="84783">

  axios({
    url: `http://hmajax.itheima.net/api/books/${id}`,
    method: 'PUT',
    data: {
      bookname,
      author,
      publisher,
      creator
    }
  }).then(() => {
    // 3.修改成功以后, 重新获取并刷新列表
    getBooksList()
    
    editModal.hide() // 隐藏弹框
  })
})

07_总结

01_渲染数据

010

02_新增数据

011

03_删除数据

012

04_编辑数据

013014

03_图片上传

01_图片上传

01_图片上传

获取 图片文件 对象

使用 FormData 携带图片文件

015

提交表单数据到服务器, 使用 图片 url 网址

016
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <!-- 文件选择元素 -->
  <input type="file" class="upload">
  <img src="" alt="" class="my-img">

  <script src="/js/axios1.2.0.js"></script>

  <script>
    // 1.文件选择元素 ==> change 改变事件
    document.querySelector('.upload').addEventListener('change', e => {
      // 2.获取图片文件
      // console.log(e.target.files[0])

      // 3.使用 FormData 携带图片文件
      const fd = new FormData()
      fd.append('img', e.target.files[0])

      // 4.提交到服务器, 获取图片 url 网址使用
      axios({
        url: 'http://hmajax.itheima.net/api/uploadimg',
        method: 'POST',
        data: fd
      }).then(result => {
        console.log(result)

        // 5.取出图片 url 网址, 用 img 标签加载显示
        const imgUrl = result.data.data.url
        document.querySelector('.my-img').src = imgUrl
      })
    })
  </script>
</body>

</html>

02_网站更换背景案例

01_网站更换背景案例

  1. 选择 图片上传, 设置 body 背景
  2. 上传成功时, 保存 url 网址
  3. 网页运行后, 获取 url 网址使用
017
javascript
// /code/js/index.js

document.querySelector('.bg-ipt').addEventListener('change', e => {
  // 1.选择图片上传, 设置 body 背景
  const fd = new FormData()
  fd.append('img', e.target.files[0])

  axios({
    url: 'http://hmajax.itheima.net/api/uploadimg',
    method: 'POST',
    data: fd
  }).then(result => {
    const imgUrl = result.data.data.url
    document.body.style.backgroundImage = `url(${imgUrl})`

    // 2. 上传成功时, "保存" 图片 url 网址
    localStorage.setItem('bgImg', imgUrl)
  })
})

// 3. 网页运行后, "获取" url 网址使用
const bgUrl = localStorage.getItem('bgImg')
bgUrl && (document.body.style.backgroundImage = `url(${bgUrl})`)

04_个人信息设置

01_介绍

01_步骤

  1. 信息渲染
  2. 头像修改
  3. 提交表单
  4. 结果提示
018

02_信息渲染

01_信息渲染

自己的用户信息: 给自己起个 外号, 并告诉服务器, 获取对应的用户信息

019
javascript
// /code/js/index.js

// 1.信息渲染 获取用户的数据
const creator = '播仔'
axios({
  url: 'http://hmajax.itheima.net/api/settings',
  params: {
    creator
  }
}).then(result => {
  const userObj = result.data.data

  // 2.回显数据到标签上
  Object.keys(userObj).forEach(key => {
    if (key === 'avatar') {
      // 赋予默认头像
      document.querySelector('.prew').src = userObj[key]
    } else if (key === 'gender') {
      // 赋予默认性别 获取性别单选框: [男 radio 元素, 女 radio 元素]
      const gRadioList = document.querySelectorAll('.gender')
      // 获取性别数字: 0 男, 1 女
      const gNum = userObj[key]
      // 通过性别数字, 作为下标, 找到对应性别单选框, 设置选中状态
      gRadioList[gNum].checked = true
    } else {
      // 赋予默认内容
      document.querySelector(`.${key}`).value = userObj[key]
    }
  })
})

03_头像修改

01_头像修改

020
javascript
// /code/js/index.js

// 1.修改头像 文件选择元素 ==> change 事件
document.querySelector('.upload').addEventListener('change', e => {
  // 2.获取头像文件
  const fd = new FormData()
  fd.append('avatar', e.target.files[0])
  fd.append('creator', creator)

  // 3.提交服务器并更新头像
  axios({
    url: 'http://hmajax.itheima.net/api/avatar',
    method: 'PUT',
    data: fd
  }).then(result => {
    const imgUrl = result.data.data.avatar

    // 4.把新的头像回显到页面上
    document.querySelector('.prew').src = imgUrl
  })
})

04_信息修改

01_信息修改

021
javascript
// /code/js/index.js

// 1.提交表单 保存修改 ==> 点击
document.querySelector('.submit').addEventListener('click', () => {
  // 2.收集表单信息
  const userForm = document.querySelector('.user-form')
  const userObj = serialize(userForm, { hash: true, empty: true })
  userObj.creator = creator
  userObj.gender = +userObj.gender // 性别数字 字符串, 转成数字类型

  // 3.提交到服务器保存
  axios({
    url: 'http://hmajax.itheima.net/api/settings',
    method: 'PUT',
    data: userObj
  })
})

05_Bootstrap 提示框

01_Bootstrap 提示框

022
javascript
// /code/js/index.js

// 提交表单 保存修改 ==> 点击
document.querySelector('.submit').addEventListener('click', () => {
  // 收集表单信息
  const userForm = document.querySelector('.user-form')
  const userObj = serialize(userForm, { hash: true, empty: true })
  userObj.creator = creator
  userObj.gender = +userObj.gender // 性别数字 字符串, 转成数字类型

  // 提交到服务器保存
  axios({
    url: 'http://hmajax.itheima.net/api/settings',
    method: 'PUT',
    data: userObj
  }).then(result => {
    // 1.创建 toast 提示框对象
    const toastDom = document.querySelector('.my-toast')
    const toast = new bootstrap.Toast(toastDom)

    // 2.调用 show 方法 ==> 显示提示框
    toast.show()
  })
})