js要点整理-13

85 阅读2分钟

DOM尺寸

获取元素偏移量

针对于参考父级 的 顶部与左侧 的距离

offsetParent

获取到元素的参考父级

offsetLeft / offsetTop

  • 获取的事元素左边的偏移量和上边的偏移量
    • offsetLeft 该元素相对于参考父级的左侧偏移量
    • offsetTop 该元素相对于参考父级的上侧偏移量
    • 获取到的是一个数字, 没有 px 单位

获取元素尺寸

visibility: hidden 元素在页面占位

offsetWidth 和 offsetHeight

  • offsetWidth: 获取元素内容 + padding + border 的宽度
  • offsetHeight: 获取元素内容 + padding + border 的高度

clientWidth 和 clientHeight

  • clientWidth 获取元素内容 + padding 的宽度
  • clientHeight 获取元素内容 + padding 的高度

获取浏览器窗口尺寸

可视区域的尺寸(不包含滚动条)

  • document.documentElement.clientWidth: 浏览器可视窗口的宽度
  • document.documentElement.clientHeight: 浏览器可视窗口的高度

浏览器窗口尺寸(含滚动条)

  • window.innerWidth: 浏览器窗口的宽度
  • window.innerHeight: 浏览器可视窗口的高度

实例(分页,瀑布流)

利用数据, 创建一个合理的字符串, 然后利用这个字符串进行页面渲染

        /**
         *  分页的功能
         * 
         *      1. 刚打开页面
         *          1.1 截取部分数据, 渲染页面
         *          1.2 调整页码
         *          1.3 调整上下页按钮的样式
         * 
         *      2. 点击上一页
         *          2.1 判断能不能去上一页
         *          2.2 截取部分数据, 渲染页面
         *          2.3 调整页码
         *          2.4 调整上下页按钮的样式
         * 
         *      3. 点击下一页
         *          3.1 判断能不能去下一页
         *          3.2 截取部分数据, 渲染页面
         *          3.3 调整页码
         *          3.4 调整上下页按钮的样式
         * 
         *      4. 切换每页展示数据的数量
         *          4.1 调整每页展示的数量
         *          4.2 截取部分数据, 渲染页面
         *          4.3 调整页码
         *          4.4 调整上下页按钮的样式
         * 
         *  逻辑:
         *      0. 创建一个渲染函数
         *          0.1 截取部分数据
         *          0.2 调整页码
         *          0.3 调整按钮样式
         * 
         *      1. 初次打开页面
         *          1.1 直接调用
         * 
         *      2. 点击上一页按钮
         *          2.1 判断能不能去上一页
         *          2.2 调整当前页
         *          2.3 调用渲染函数
         * 
         *      3. 点击下一页按钮
         *          3.1 判断能不能去下一页
         *          3.2 调整当前页
         *          3.3 调用渲染函数
         * 
         *      4. 切换每页展示数量
         *          4.1 切换展示的数量
         *          4.2 调用渲染函数
        */

具体实现

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .header,
        .footer {
            width: 1200px;
            margin: 0 auto;
            background-color: skyblue;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 50px;
            height: 120px;
            color: #fff;
        }

        .footer {
            height: 300px;
        }

        ul,
        li {
            list-style: none;
        }

        ul {
            width: 1200px;
            display: flex;
            flex-wrap: wrap;
            margin: 0 auto;
            justify-content: space-between;
            padding-top: 10px;
        }

        li {
            width: 290px;
            border: 1px solid #333;
            margin-bottom: 10px;
            padding: 5px;
            box-sizing: border-box;
        }

        li>img {
            width: 278px;
            display: block;
        }

        .pagination {
            width: 1200px;
            margin: 10px auto;
            height: 50px;
            display: flex;
            align-items: center;
        }

        .pagination>.prev,
        .pagination>.next {
            width: 50px;
            height: 30px;
            cursor: pointer;
            background-color: orange;
            font-size: 24px;
            color: #fff;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .pagination>.disable {
            cursor: not-allowed;
            background-color: #ccc;
        }

        .pagination>.total {
            font-size: 30px;
            font-weight: 700;
            margin: 0 20px;
        }

        .pagination>select {
            font-size: 22px;
            padding-left: 20px;
            margin-left: 30px;
        }
    </style>
</head>

<body>
    <div class="header">顶部导航</div>

    <div class="pagination">
        <span class="prev">&lt;</span>
        <span class="total">1 / 100</span>
        <span class="next">&gt;</span>
        <select>
            <option value="4">4</option>
            <option value="8">8</option>
            <option value="12">12</option>
            <option value="16">16</option>
        </select>
    </div>

    <ul>

    </ul>
    <div class="footer">底部导航</div>
    <script src="./dm_list.js"></script>
    <script>
        // console.log(list)

        // 0. 获取标签
        var total = document.querySelector('.total')
        var prev = document.querySelector('.prev')
        var next = document.querySelector('.next')
        var select = document.querySelector('select')

        // 0. 创建全局变量 (在当前 JS 中, 任何一个地方都能使用)
        var currentNum = 1  // 默认在 第一页
        var pageSize = 4    // 默认每页展示 4 条数据
        var totalNum = 0    // 计算总页码

        // 0. 创建一个渲染函数
        function bindHtml() {
            /**
             *  0.1 截取部分数据, 渲染页面
             * 
             *      假设 当前是第 1 页  每页展示 4 条
             *              页码 === 1          =>      [0]~[3]
             *              页码 === 2          =>      [4]~[7]
             *              页码 === 3          =>      [8]~[11]
             * 
             *      我们假设 当前页的数字存储在 currentNum 中, 每页展示多少条的数字存储在 pageSize 中
             * 
             *          第一版
             *          开始下标: (currentNum - 1) * pageSize
             *          结束下标: currentNum * pageSize - 1
             * 
             *      但是 我们用的截取的方法参数有一个特点: 包前不包后, 所以开始下标不变, 结束下标 需要 + 1
             * 
             *          第二版
             *          开始下标: (currentNum - 1) * pageSize
             *          结束下标: currentNum * pageSize - 1 + 1
             * 
             *      所以最终的优化版本
             * 
             *          第三版
             *          开始下标: (currentNum - 1) * pageSize
             *          结束下标: currentNum * pageSize
            */
            var newArr = list.slice((currentNum - 1) * pageSize, currentNum * pageSize)

            var htmlStr = ""
            for (var i = 0; i < newArr.length; i++) {
                htmlStr += `
                    <li>
                        <img src="${newArr[i].pic}" alt="">
                        <p>${newArr[i].name}</p>
                        <p>城市: ${newArr[i].city}</p>
                        <p>地址: ${newArr[i].address}</p>
                        <p>价格: ${newArr[i].price}</p>
                        <p>时间: ${newArr[i].showTime}</p>
                    </li>
                `
            }
            document.querySelector('ul').innerHTML = htmlStr

            // 0.2 调整页码
            totalNum = Math.ceil(list.length / pageSize)
            total.innerHTML = currentNum + ' / ' + totalNum

            // 0.3 调整按钮样式
            prev.className = currentNum === 1 ? 'prev disable' : 'prev'
            next.className = currentNum === totalNum ? 'next disable' : 'next'
        }

        // 1. 初次打开页面 直接调用
        bindHtml()

        // 2. 点击上一页
        prev.onclick = function () {
            // 2.1 判断能不能去上一页
            if (currentNum === 1) return

            // 2.2 调整页码
            currentNum--

            // 2.3 重新渲染
            bindHtml()
        }

        // 3. 点击下一页
        next.onclick = function () {
            // 3.1 判断能不能去下一页
            if (currentNum === totalNum) return

            // 3.2 调整页码
            currentNum++

            // 3.3 重新渲染
            bindHtml()
        }

        // 4. 切换每页展示多少条
        select.onchange = function () {
            // console.log('选择框的内容改变了', select.value - 0)

            currentNum = 1
            
            // 修改每页展示多少条
            pageSize = select.value - 0

            // 重新渲染页面
            bindHtml()
        }
    </script>
</body>

</html>

瀑布流

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        .header,
        .footer {
            width: 1200px;
            margin: 0 auto;
            background-color: skyblue;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 50px;
            height: 120px;
            color: #fff;
        }

        .footer {
            height: 300px;
        }

        ul,
        li {
            list-style: none;
        }

        ul {
            width: 1200px;
            display: flex;
            flex-wrap: wrap;
            margin: 0 auto;
            justify-content: space-between;
            padding-top: 10px;
        }

        li {
            width: 290px;
            border: 1px solid #333;
            margin-bottom: 10px;
            padding: 5px;
            box-sizing: border-box;
        }

        li>img {
            width: 278px;
            display: block;
        }

        .loadding {
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;

            display: none;
        }
    </style>
</head>

<body>
    <div class="header">顶部导航</div>
    <ul></ul>
    <div class="loadding">
        <img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fhbimg.b0.upaiyun.com%2F42c725b3935a1ce3e32897b9995c1b6a2e921d335690-Ck6vZO_fw658&refer=http%3A%2F%2Fhbimg.b0.upaiyun.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1669994288&t=3e6b58c142daa3e4fef899cd7b6e9a0b"
            alt="">
    </div>
    <div class="footer">底部导航</div>
    <script src="./dm_list.js"></script>

    <script>
        /**
         *  瀑布流: 是目前主流的一个前端分页方式
         * 
         *  1. 打开页面渲染一套数据
         * 
         *  2. 当页面滚动到某一个位置的时候, 重新请求新的数据
         * 
         *  逻辑:
         *      封装一个渲染函数
         *      首次打开页面的时候调用
         *      当页面滚动到某一个位置的时候, 重新调用渲染函数, 拼接上新的数据
         * 
         * 
         *  我们规定 每页固定展示 8 条数据, 因为要首次渲染的时候, 撑满首页
        */
        var myUl = document.querySelector('ul')
        var loadding = document.querySelector('.loadding')

        // 0. 全局变量
        var currentNum = 1                                  // 表示当前页
        var pageSize = 8                                    // 表示每页展示多少条 (这个变量不会被更改)
        var totalNum = Math.ceil(list.length / pageSize)    // 计算总页码
        var flag = true                                     // 作为一个开关变量, 用于控制是否请求新数据

        // 0. 封装渲染函数
        function bindHtml() {
            var newArr = list.slice((currentNum - 1) * pageSize, currentNum * pageSize)

            var htmlStr = ""
            for (var i = 0; i < newArr.length; i++) {
                htmlStr += `
                    <li>
                        <img src="${newArr[i].pic}" alt="">
                        <p>${newArr[i].name}</p>
                        <p>城市: ${newArr[i].city}</p>
                        <p>地址: ${newArr[i].address}</p>
                        <p>价格: ${newArr[i].price}</p>
                        <p>时间: ${newArr[i].showTime}</p>
                    </li>
                  `
            }

            // 因为瀑布流需要的是拼接数据, 所以此处不应该使用 = , 而是使用 +=
            myUl.innerHTML += htmlStr
        }

        // 1. 首次打开页面的时候调用
        bindHtml()

        // 2. 给页面添加滚动事件
        window.onscroll = function () {
            // 2.1 如果当前页 === 总页码    代表没有下一页了, 所以这个事件可以不执行了
            if (currentNum === totalNum) return

            /**
             *  2.2 如果代码能够执行到这个位置, 说明还有数据
             * 
             *  但是需要在 UL 的底边到达 页面的可视区域的时候, 在加载新数据
             * 
             * 
             *  页面卷去的高度 + 浏览器可视区域的高度 > UL 顶部偏移量 + UL 的高度       满足这个条件 加载新数据
             * 
             *  页面卷去的高度 + 浏览器可视区域的高度 <= UL 顶部偏移量 + UL 的高度      满足这个条件 不需要加载新数据 直接 return
            */
            // 页面卷去的高度
            var docHeight = document.documentElement.scrollTop
            // 浏览器可视区域的高度
            var winHeight = document.documentElement.clientHeight
            // UL 顶部偏移量
            var ULTop = myUl.offsetTop
            // UL 的高度
            var ULHeight = myUl.offsetHeight
            if (docHeight + winHeight <= ULTop + ULHeight) return

            // 2.3 如果代码执行到这里, 说明后续还有数据, 并且到了加载新数据的时候了


            // 2.3.1 查看开关变量, 是否允许我们请求
            if (!flag) return
            // 2.3.2 开始请求数据前, 关闭开关变量, 直到这一次请求完毕的时候, 才能重新发起请求
            flag = false

            
            // 数据请求前 打开 loadding
            loadding.style.display = 'flex'
            console.log('此时请求了 1 次新数据')
            
            setTimeout(function () {
                currentNum++
                bindHtml()
                loadding.style.display = 'none'

                // 2.3.3 此时这一次请求已经完毕了, 可以打开开关, 允许我们发送第二次请求, 加载新的数据
                flag = true
            }, 2000)
            
        }
    </script>
</body>

</html>