JS-15 (小案例)更换背景图、倒计时、操作渲染页面、渲染表格 (选中,全选)、(新增)、(排序)、(删除)

88 阅读5分钟

更换背景图

css样式

<style>
        * {
            padding: 0;
            margin: 0;
        }

        .overlay {
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0;
            left: 0;
            background-color: rgba(0, 0, 0, .3);
        }

        .img_box {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 300px;
            height: 450px;
            background-color: aliceblue;
            border-radius: 10px;
        }

        .img_box h2 {
            text-align: center;
            margin: 15px 0;
        }

        .div_img {
            width: 200px;
            height: 100px;
            margin: 10px auto;
        }

        .div_img img {
            width: 100%;
            height: 100%;
        }

        .close {
            display: none;
        }
    </style>

html结构

<button id="show_img_box">打开弹出框</button>

    <!-- 遮罩层, 一般没有事件, 但是有的时候会加一个需求, 就是点击遮罩层关闭弹出框和遮罩层 -->
    <div class="overlay close"></div>

    <!-- 弹出框 -->
    <div class="img_box close">
        <h2>请选择背景图</h2>

        <div class="div_img">
            <img data-name="01.webp" id="img_1" src="./img/01.webp" alt="">
        </div>
        <div class="div_img">
            <img data-name="02.jpg" id="img_2" src="./img/02.jpg" alt="">
        </div>
        <div class="div_img">
            <img data-name="03.jpg" id="img_3" src="./img/03.jpg" alt="">
        </div>

        <button id="close_img_box">关闭弹出框</button>
    </div>

JS

/**
         *  1. 点击按钮 弹出弹出框
         *  2. 点击弹出框内的内容
         *      2.1 点击图片
         *          * 此时将对应的图片渲染到 body 的背景图中
         *      2.2 点击关闭按钮
         *          * 关闭弹出框和遮罩层
         * 
         * 
         *  逻辑:
         *      1. 删掉 遮罩层和弹框两个 DIV 的 close 类名
         *
         
         2.1 点击图片的时候想办法知道点的是那个图片, 或者想办法拿到 图片的地址, 然后更改 body 的背景图
         *      2.2 给 遮罩层和弹框两个 DIV 添加 close 类名
        */
        
        // 0. 获取标签
        var showImgBox = document.querySelector('#show_img_box')    // 打开按钮
        var closeImgBox = document.querySelector('#close_img_box')    // 关闭按钮
        var overlay = document.querySelector('.overlay')    // 遮罩层
        var imgBox = document.querySelector('.img_box')     // 弹出框
        var divImg = document.querySelectorAll('.div_img')  // 图片的包含框, 一会要给他加点击事件

        // 添加逻辑

        // 1. 点击按钮: 删掉 遮罩层和弹框两个 DIV 的 close 类名
        showImgBox.onclick = function () {
            overlay.classList.remove('close')
            imgBox.classList.remove('close')
        }

        // 2.1 点击图片的时候想办法知道点的是那个图片, 或者想办法拿到 图片的地址, 然后更改 body 的背景图
        // divImg[0].onclick = function () {}
        // divImg[1].onclick = function () {}
        // divImg[2].onclick = function () {}


        /**
         *  所有的标签添加点击事件之后, 这个事件的执行函数, 会默认接收一个参数
         *  我们一般会将这个参数命名伪 event    
         *      但是名字有点麻烦, 所以有人会写 ev       现在更加习惯写 e
         *  但是函数的形参拼写不重要, 所以怎么写都行
         * 
         *  这个形参 e, 是一个对象, 里边有很多属性, 其中一个叫做 target
         *  这个属性的值, 就是你点击的标签
         * 
         *  关于这个形参 后续会详细讲解
        */
        for (var i = 0; i < divImg.length; i++) {
            divImg[i].onclick = function (e) {
                // console.log(e.target)
                // console.log(e.target.dataset)
                // console.log(e.target.dataset.name)

                document.querySelector('body').style.backgroundImage = 'url(./img/' + e.target.dataset.name + ')'

                // document.querySelector('body').style.backgroundImage = 'url(./img/' + '01.webp' + ')'
                // document.querySelector('body').style.backgroundImage = 'url(./img/01.webp)'
                // document.querySelector('body').style.backgroundImage = 'url(./img/02.jpg)'
                // document.querySelector('body').style.backgroundImage = 'url(./img/03.jpg)'
            }
        }
    
    
        // 2.2 给 遮罩层和弹框两个 DIV 添加 close 类名
        closeImgBox.onclick = function () {
            overlay.classList.add('close')
            imgBox.classList.add('close')
        }

成果图

image.png

倒计时

HTML

<button id="get_msg">获取验证码</button>
<p style="display: none">验证码将在 <span id="timer"></span> 秒后重新获取</p>

JS

/**
         *  获取验证码
        */

        // 0. 获取标签
        var getMsg = document.querySelector('#get_msg')
        var timer = document.querySelector('#timer')
        var pEl = document.querySelector('p')

        // 0. 添加逻辑

        /**
         *  1. 点击 按钮 获取验证码
         *  2. 打开 提示信息 (禁用按钮)
         *  3. 开始倒计时
         *  4. 当时间到达, 关闭提示信息 (开启按钮)
        */

        getMsg.onclick = function (e) {
            // 打开提示信息
            pEl.style.display = 'block'
            // getMsg.disabled = true
            // 禁用按钮
            e.target.disabled = true

            // 规定的按钮倒计时时间
            var timeOut = 5

            // 修改提示文本, 为正确的时间
            timer.innerText = timeOut

            // 开启倒计时
            var timerId = setInterval(function () {
                timeOut--
                // 小问题: 如何优化条件
                if (!timeOut) {
                    // 关闭定时器
                    clearInterval(timerId)
                    // 关闭提示信息
                    pEl.style.display = 'none'
                    // 取消禁用按钮
                    e.target.disabled = false
                } else {
                    timer.innerText = timeOut
                }
            }, 1000)

        }

成果图

123.gif

操作渲染页面

HTML

<ul>
    <li>
        <img scr=' '>
        <span>嗨嗨嗨</span>
    </li>
</ul>

CSS

    <style>
        * {
            padding: 0;
            margin: 0;
        }

        ul {
            list-style: none;
            display: flex;
            width: 400px;
            flex-wrap: wrap;
        }

        li {
            width: 70px;
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
        }

        li img {
            width: 40px;
        }
    </style>

JS

var dataList = [
    {
        navid: 1,
        title: "嗨购超市",
        imgurl: "https://m.360buyimg.com/mobilecms/s120x120_jfs/t1/125678/35/5947/4868/5efbf28cEbf04a25a/e2bcc411170524f0.png",
    },]
    数组里面还有很多数据 就拿了一个
    
    console.log(dataList)

        /**
         *  扩展:
         *      字符串需要使用 '' 或者 "" 包裹, 但是不能换行, 内部也不能书写变量
         * 
         *      如果想要书写换行或者书写变量, 那么需要使用 ``
         * 
         *      如果需要在 `` 内 书写换行, 那么直接换行就行
         *      如果需要在 `` 内书写变量 需要使用 ${} 将变量包裹
        */

        /**
         *  创建一个渲染函数, 页面打开的时候调用
        */

        function bindHtml() {
            var str = ''
            for (var i = 0; i < dataList.length; i++) {
                str += `
                    <li>
                        <img src="${dataList[i].imgurl}" alt="">
                        <p>${dataList[i].title}</p>
                    </li>
                `
            }
            // console.log(str)
            document.querySelector('ul').innerHTML = str
        }

        bindHtml()

成果图

image.png

渲染表格 (选中,全选)、(新增)、(排序)、(删除)

CSS

<style>
        * {
            padding: 0;
            margin: 0;
        }

        html,
        body {
            width: 100%;
            height: 100%;
        }

        table {
            border-collapse: collapse;
            width: 100%;
        }

        th,
        td {
            border: 1px solid black;
            padding: 8px;
            text-align: center;
        }

        th {
            background-color: rgb(162, 162, 162);
        }

        .overlay {
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, .3);
            position: fixed;
            top: 0;
            left: 0;
        }

        .add_user_box {
            width: 350px;
            height: 130px;
            background-color: beige;
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            border-radius: 15px;
            padding: 20px;
        }

        .add_user_box input {
            width: 300px;
        }

        .btn_box {
            width: 100%;
            position: absolute;
            bottom: 30px;
            display: flex;
            justify-content: center;
        }

        .btn_box button {
            width: 100px;
            height: 30px;
        }

        .close {
            display: none;
        }
    </style>

HTML

<button id="sort_btn">排序</button>
    <button id="add_btn">新增</button>
    <table></table>

    <!-- 遮罩层 -->
    <div class="overlay close"></div>

    <!-- 弹出层 -->
    <div class="add_user_box close">
        姓名: <input type="text" class="username">
        <br>
        年龄: <input type="text" class="userage">
        <br>
        城市: <input type="text" class="usercity">
        <br>
        <br>
        <div class="btn_box">
            <button class="close_box_btn">取消</button>
            <button class="add_user_btn">新增用户</button>
        </div>
    </div>

JS

 var data = JSON.parse(window.localStorage.getItem('data')) || [
            {
                status: true,
                id: 1,
                name: '张三',
                age: 25,
                city: '北京',
                set: '<button class="del_btn" data-id="1">删除</button>'
            },
            {
                status: false,
                id: 2,
                name: '李四',
                age: 30,
                city: '上海',
                set: '删除'
            },
            {
                status: true,
                id: 3,
                name: '王五',
                age: 22,
                city: '杭州',
                set: '删除'
            }
        ]

        // 页面打开时调用渲染函数
        bindHtml()

        // 创建一个渲染函数
        function bindHtml() {
            document.querySelector('table').innerHTML = ""
            var checkedNum = 0
            for (var q = 0; q < data.length; q++) {
                data[q].status && checkedNum++
            }

            // ==================创建表头内容开始==================
            var headerArr = ['选择', '编号', '姓名', '年龄', '城市', '操作']
            var headerTr = document.createElement('tr')
            for (var j = 0; j < headerArr.length; j++) {
                var headerTh = document.createElement('th')
                if (j === 0) {
                    var inp = document.createElement('input')
                    inp.type = 'checkbox'
                    inp.className = 'check_all'
                    inp.checked = checkedNum === data.length
                    headerTh.appendChild(inp)
                } else {
                    headerTh.innerHTML = headerArr[j]
                }
                headerTr.appendChild(headerTh)
            }
            document.querySelector('table').appendChild(headerTr)
            // ==================创建表头内容结束==================

            // ==================创建表格内容开始==================
            for (var i = 0; i < data.length; i++) {
                var myTr = document.createElement('tr')
                var dataKeys = Object.keys(data[i])
                for (var k = 0; k < dataKeys.length; k++) {
                    var myTd = document.createElement('td')
                    if (data[i][dataKeys[k]] === true || data[i][dataKeys[k]] === false) {
                        var inpItems = document.createElement('input')
                        inpItems.type = 'checkbox'
                        inpItems.className = 'check_item'
                        inpItems.checked = data[i][dataKeys[k]]
                        inpItems.dataset.id = i + 1
                        myTd.appendChild(inpItems)
                    } else if (data[i][dataKeys[k]] === '删除') {   // 如果这个属性的值是: '删除', 那么渲染为一个 button 标签
                        var myBtn = document.createElement('button')    // 创建一个按钮
                        myBtn.innerHTML = '删除'                        // 给标签添加文本
                        myBtn.className = 'del_btn'                     // 给标签添加类名, 将来在事件委托中可以作为一个标识寻找到按钮
                        myBtn.dataset.id = i + 1                        // 给按钮添加一个特别的标识, 当你点击的时候能够利用这个数据 直到要删除哪一个
                        myTd.appendChild(myBtn)                         // 将按钮添加到单元格中
                    } else {
                        myTd.innerHTML = data[i][dataKeys[k]]
                    }
                    myTr.appendChild(myTd)
                }

                document.querySelector('table').appendChild(myTr)
            }
            // ==================创建表格内容结束==================

            // ==================持久化数据==================
            window.localStorage.setItem('data', JSON.stringify(data))
        }

        var myTable = document.querySelector('table')
        myTable.onclick = function (e) {
            // ==================全选功能(事件委托)开始==================
            if (e.target.className === 'check_all') {
                for (var i = 0; i < data.length; i++) {
                    data[i].status = e.target.checked
                }

                bindHtml()
            }
            if (e.target.className === 'check_item') {
                for (var k = 0; k < data.length; k++) {
                    if (e.target.dataset.id - 0 === data[k].id) {
                        data[k].status = e.target.checked
                    }
                }

                bindHtml()
            }
            // ==================全选功能(事件委托)结束==================

            // ==================删除功能(事件委托)开始==================
            if (e.target.className === "del_btn") {
                // var res = window.confirm('您确定删除吗?')
                // console.log('现在要删除一个内容', res)
                if (!confirm('您确定删除吗?')) return

                // 改变数据
                console.log('如果代码能够执行到这里, 说明需要删除', e.target.dataset.id)
                // data.splice(0, 1)
                // data.splice(1, 1)
                // data.splice(2, 1)
                data.splice(e.target.dataset.id - 1, 1)

                // 重新渲染页面
                bindHtml()
            }
            // ==================删除功能(事件委托)结束==================
        }

        // ==================排序功能开始==================
        var sortBtn = document.querySelector('#sort_btn')
        var num = 0
        sortBtn.onclick = function () {
            num++
            if (num === 1) {
                data.sort(function (a, b) { return a.age - b.age })
            } else if (num === 2) {
                data.sort(function (a, b) { return b.age - a.age })
            } else {
                data.sort(function (a, b) { return a.id - b.id })
                num = 0
            }
            bindHtml()
        }
        // ==================排序功能结束==================

        // ==================新增功能开始==================
        var addBtn = document.querySelector('#add_btn')
        var overlay = document.querySelector('.overlay')
        var addUserBox = document.querySelector('.add_user_box')
        addBtn.onclick = function () {
            overlay.classList.remove('close')
            addUserBox.classList.remove('close')
        }
        var addUserBtn = document.querySelector('.add_user_btn')
        addUserBtn.onclick = function () {
            var nameEl = document.querySelector('.username')
            var ageEl = document.querySelector('.userage')
            var cityEl = document.querySelector('.usercity')

            var nameValue = nameEl.value
            var ageValue = ageEl.value
            var cityValue = cityEl.value

            if (nameValue === '' || ageValue === '' || cityValue === '') return alert('您的输入框有一个为空, 请补全输入框')

            var obj = {
                status: false,
                id: data.length + 1,
                name: nameValue,
                age: ageValue - 0,
                city: cityValue,
                set:'删除'
            }
            data.push(obj)

            bindHtml()

            nameEl.value = ''
            ageEl.value = ''
            cityEl.value = ''

            closeBoxFn()
        }
        var closeBoxBtn = document.querySelector('.close_box_btn')
        closeBoxBtn.onclick = closeBoxFn
        function closeBoxFn() {
            overlay.classList.add('close')
            addUserBox.classList.add('close')
        }
        // ==================新增功能结束==================

成果图

01.gif