js案例

124 阅读3分钟

1.运用for 与 语句解决问题

 求 2000-3000 内的所有闰年
     * 
     *      逻辑:
     *          1. 找到 2000~3000 所有的数字
     *          2. 判断这个数字是不是闰年
 新需求: 每 打印 4 次闰年, 换行一次
     * 
     *      思路: 创建一个新的变量作为计数器
                var sum = 0 // 作为计数器
                for (var i = 2000; i < 3001; i++) {
                    if (i % 4 === 0 && i % 100 !== 0 || i % 400 === 0) {
                    //  ' ' 有空格,将数隔开
                        document.write(i + ' ')
                        sum++   // 上述代码执行1次, 那么计数器 + 1

                        // if (sum === 4) {
                        //     document.write('<br>')
                        //     sum = 0 // 清零计数器, 方便开始新一轮的计算
                        // }

                        if (sum % 4 === 0) {
                            document.write('<br>')
                        }
                    }
                }
                 有一个三位数
     *      每个位置上的三次方之和 正好等于自身
     *
     *  帮我找出 所有的水仙花数
     *
     *
     * 举例:
     *      123
     *          1 * 1 * 1    + 2 * 2 * 2    + 3 * 3 * 3  === 是否等于 123
     *              如果等于 那么就是水仙花数
     *              否则不是
     *
     *
     *  逻辑:
     *      1. 找到所有的 三位数 (100~999)
     *      2. 找到某一个三位数的各个位置的值
     *      3. 计算三个位置上各个数字的三次方之和
     *      4. 对比 是否等于自身
    */

2.水仙花数

    1. 找到所有的 三位数 (100~999)
    for (var i = 100; i < 1000; i++) {
        // console.log(i)

        // 2. 找到某一个三位数的各个位置的值
        var gew = i % 10
        var shiw = parseInt(i / 10) % 10
        var baiw = parseInt(i / 100)

        /**
         *  3. 计算三个位置上各个数字的三次方之和
         * 
         *      **
         *          会得到 符号左边数字的 x 次幂
        */
 求三位数的第一方法    var sum = gew * gew * gew + shiw * shiw * shiw + baiw * baiw * baiw
 求三位数的第二方法    var sum = gew ** 3 + shiw ** 3 + baiw ** 3
        // 4. 对比 是否等于自身
        if (sum === i) {
            console.log(i, '是一个水仙花数')
        }
    }

3.求两个数的最大公约数

   /**
         *  求两个数字的最大公约数
         *      比如: 12 和 8
         * 
         *  什么是约数?
         *      能被这个数字整除 (余数为0)
         * 
         * 
         *      12
         *          1               √
         *          2               √
         *          3               √
         *          4               √
         *          5
         *          6               √
         *          7
         *          8
         *          9
         *          10
         *          11
         *          12               √
         * 
         * 
         *      8
         *          1               √
         *          2               √
         *          3
         *          4               √
         *          5
         *          6
         *          7
         *          8               √
         * 
         *      12 的约数
         *          1  2  3  4  6  12
         *      8 的约数
         *          1 2 4 8
         * 
         * 
         *      1. 先找到 1~12 或者 1~8 的所有数字
         *      2. 寻找 12 和 8 的公约数
         *      3. 找到所有的公约数中 最大的
        *

        // num1 和 num2 是用户输入的两个数字
        var num1 = 12
        var num2 = 8

        // num3 存储 num1 和 num2 中 最小的数字,用三元表达式
        var num3 = num1 > num2 ? num2 : num1

        // num4 用于存储最大的公约数
        var num4 = 0

        // 1. 先找到 1~12 或者 1~8 的所有数字, 为了性能更好, 我们这里选择的是 1~8 的所有数字
        for (let i = num3; i >= 1; i--) {

        // 2. 寻找 12 和 8 的公约数
        if (num1 % i === 0 && num2 % i === 0) {
            // console.log(i)   // i 是 num1 和 num2 的公约数
            // num4 = i         // 这种书写方式存储的是最后一个 公约数, 不是最大公约数,因为i是递减,所以循环到最后  i是最小值

            // 3. 找到所有的公约数中 最大的  ,因为当条件 num4 < i成立, num4 = i,但i是递减的,所以当 num4 < i, num4 = i第一次成立时,  num4就是i的最大值
            
            if (num4 < i) {
                num4 = i
            }
        }
    }

    console.log('最大公约数: ', num4)

3.求 1~30 中的所有质数

     * 
     *      如果你能够判断一个数字是不是质数, 那么你就能够完成上述案例
     *          
     * 
     *      除了1和它本身, 没有能够整除的数字
     * 
     *          7   (是质数)
     *              1~7 (除了1和它本身 就剩下 2~6)
     *              7 % 2 !== 0
     *              7 % 3 !== 0
     *              7 % 4 !== 0
     *              7 % 5 !== 0
     *              7 % 6 !== 0
     * 
     *          8   (不是一个质数)
     *              1~8  (除了1和它本身 就剩下 2~7)
     *              8 % 2 === 0
     *              8 % 3 !== 0
     *              8 % 4 === 0
     *              8 % 5 !== 0
     *              8 % 6 !== 0
     *              8 % 7 !== 0
     * 
     *          9   (不是一个质数)
     *              1~9   (除了1和它本身 就剩下 2~8)
     *              9 % 2 !== 0
     *              9 % 3 === 0
     *              9 % 4 !== 0
     *              9 % 5 !== 0
     *              9 % 6 !== 0
     *              9 % 7 !== 0
     *              9 % 8 !== 0
     * 
     *      假设 数字 为 n
     *          1. 找到 2~n-1 的所有数字
     *          2. 找有没有能够和 n 完成 整除的 数字
     *                  有 代表 不是质数
     *                  没有 代表 是质数
    */


    // 当前案例为 判断一个数字是不是质数=============================================

    // 假设 数字 为 n
     var n = 6
     var sum = 0 // 用于完成计数器, 当 for 循环内部的 if 语句 执行的时候, 会改变 sum 的值

    // // 1. 找到 2~n-1 的所有数字
           for (var i = 2; i < n; i++) {

    //     // 2. 找有没有能够和 n 完成 整除的 数字
           if (n % i === 0) {
    //         // console.log(i, '当你看到我的时候 说明有一个数字能够和', n, '完成整除')

    //         // 当前 分支内 如何修改 sum 的值(修改为什么)  并不重要, 重要的是 不能等于 初始值
            sum++
    //         // sum = 100
    //         // sum = true
    //     }
    // }

    // // 只要 当前 sum === 0 就证明 上述的 循环内的分支没有执行过
           if (sum === 0) {
           console.log(n, '是一个质数')
     }
    // =============================================================================


    // 求 1~30 以内的所有质数

    // 当前循环只是拿到了 1~30 的所有数字, 没有任何特殊含义, 但是这样写 会将 数字 1 也算作 质数
    for (var n = 1; n < 31; n++) {  
        var sum = 0 // 用于完成计数器, 当 for 循环内部的 if 语句 执行的时候, 会改变 sum 的值   var sum = 0  必须在外循环里面,使得sum不断参与循环变为0,如果在外循环外面  sum 就会因为循环得到值不段变大让结果出错


        // 1. 找到 2~n-1 的所有数字
        for (var i = 2; i < n; i++) {
            // 2. 找有没有能够和 n 完成 整除的 数字
            if (n % i === 0) {
                sum++
            }
        }

        // 只要 当前 sum === 0 就证明 上述的 循环内的分支没有执行过
        if (sum === 0) {
            console.log(n, '是一个质数')
        }
    }


    /**
     *  循环嵌套 其实就是 在一个 for 循环中, 又书写了一个 for 循环
     * 
     *  注意点就是 两个 循环 初始化的变量 不要相同
    */

内外双循环案例一

     for (var j = 0; j < 5; j++) {
         for (var i = 0; i < 5; i++) {
            document.write(i)
        }
        document.write('  ') //有空格
  //j先运行代表了大范围,代表组。i代表了小范围,j动一下,i就动一圈。这j代表了组,i代表了每组几个

image.png

内外双循环案例二

  for (var j = 0; j < 5; j++) {
             for (var i = 0; i < 5; i++) {
                document.write('*')
            }
            document.write('<br>')//换行
        }

image.png

内外双循环案例三 三角形

   三角形
         *          第一行: 一列
         *          第二行: 二列
         *          第三行: 三列
         *          以此类推.....
        */

        // 外层循环 决定有多少行
             for (var j = 0; j < 5; j++) {
             // 内层循环 决定 有多少 列
             for (var i =0; i <= j; i++) {
                 document.write('*')
         }
            document.write('<br>')
         }

image.png

内外双循环案例三 九九算术乘法表

            for (var j = 1; j < 10; j++) {
            // 内层循环 决定 有多少 列
            for (var i = 1; i <= j; i++) {
                // 1 * 1 = 1            5 * 6 = 30
                document.write(j, ' * ', i, ' = ', j * i + ' ')
            }
            document.write('<br>')
        }
        

image.png

随机函数 ->

 要求封装一个函数, 这个函数能够计算出一个 0~10 的随机整数
    function fn() {
        // 1. 先拿到随机数
        var num = Math.random()

        // 2. 将随机数放大 10 倍
        num *= 10

        // 3. 将随机数取整 (四舍五入)
        num = Math.round(num)

        // 4. 将计算后的随机数 返回
        return num
    }

    console.log(fn())

随机概率 这里调用 上面写的随机涵数

    // 基本版
     var obj = {}
     for (var i = 1; i <= 11000; i++) {
        var num = fn()
//         // console.log(i, '===>', num)
        if (obj[num] === undefined) {   //obj[num] 是对象 当随机数在对象里第一次出现,也就是undefined
//             // 当前分支执行, 表明 num 内部存储的随机数字 是 第一次出现
           obj[num] = 1   //   假如是2就是第二次出现 
        } else {
            // 当前分支执行, 表明 num 内部存储的随机数字 之前出现过
             // obj[num] = obj[num] + 1
             obj[num] += 1
       }
     }
     console.log(obj)
     

// 随机概率 优化1

     var obj = {}
     for (var i = 1; i <= 11000; i++) {
         var num = fn()
        // if (obj[num] === undefined) {
         if (!obj[num]) {  // !obj[num] 这里是个表达式做判断 ,用!取相反布尔值  当   obj[num] === undefined  时 原本为假 用!则变为真 使得if条件成立
    //    obj[num] 是用对象取里面的属性名的值 又因为是从i = 1开始  obj[num]的值取不到零
    //         // 当前分支执行, 表明 num 内部存储的随机数字 是 第一次出现
         obj[num] = 1
        } else {
    //         // 当前分支执行, 表明 num 内部存储的随机数字 之前出现过
        obj[num] += 1
         }
     }
     console.log(obj)
     

// 随机概率 最终版本

        var obj = {}
        for (var i = 1; i <= 11000; i++) {
            var num = fn()
                     // obj[num]  是表达式当他的值不是 undefined 条件1成立 否则 条件2成立
            obj[num] = obj[num] ? obj[num] + 1 : 1
        }
        console.log(obj)

求两个的时间差

  var tee = new Date()
    var ter = new Date(2021, 8, 13, 12, 36)
    var sr = tee - ter
    console.log(sr)


    console.log(Math.round(sr / 1000)) // 秒
    var st = Math.round(sr / 1000)
    console.log(st / 31536000)  // 一年多
    console.log(st % 31536000)  这个可求余下的月

    var tgf = st % 31536000
    console.log(tgf / 2592000)  // 11月多
    console.log(tgf % 2592000)
    var you = tgf % 2592000
    console.log(you / 86400)  // 14天
    console.log(you % 86400)
    var yi = you % 86400
    console.log(yi / 3600)  //9小时
    console.log(yi % 3600)
    var  tt  =  yi % 3600
    console.log(tt / 60)  // 分钟
    var nb  = tt / 60
    console .log('差',Math.floor(st / 31536000)+'年',Math.floor(tgf / 2592000)+'月',Math.floor(you / 86400)+'天',Math.floor(yi / 3600)+'小时',Math.ceil(nb)+'分钟')
    
    
    
    
    
    
    
    
    
    

瀑布流

<!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>
<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&#x26;refer=http%3A%2F%2Fhbimg.b0.upaiyun.com&#x26;app=2002&#x26;size=f9999,10000&#x26;q=a80&#x26;n=0&#x26;g=0n&#x26;fmt=auto?sec=1669994288&#x26;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 = false                                   // 作为一个开关变量, 用于控制是否请求新数据

    // 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
        myUl.innerHTML = myUl.innerHTML + htmlStr
    }

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

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

        /**
         *  2.2 如果代码能够执行到这个位置, 说明还有数据
         * 
         *  但是需要在 UL 的底边到达 页面的可视区域的时候, 在加载新数据
         * 
         * 
         *  页面卷去的高度 + 浏览器可视区域的高度 > UL 顶部偏移量 + UL 的高度       满足这个条件 加载新数据
         * 
         *  页面卷去的高度 + 浏览器可视区域的高度 <= UL 顶部偏移量 + UL 的高度      满足这个条件 不需要加载新数据 直接 return
        */
        // 页面卷去的高度  Bom 浏览器滑动高度
        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  //  表达式的布尔值为true时成立,不是给flag赋变量的值为true 为真 , 
        // 2.3.2 开始请求数据前, 关闭开关变量, 直到这一次请求完毕的时候, 才能重新发起请求
        flag = true
        
        // 数据请求前 打开 loadding
        loadding.style.display = 'flex'
        console.log('此时请求了 1 次新数据')
        
        setTimeout(function () {
            // 不断添加页
            currentNum++
            bindHtml()  // 2 秒后启动
            loadding.style.display = 'none'

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

</body>

</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>
    <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
        }
        // 初次打开页面 直接调用  不能在涵数本身   function bindHtml() 调用 其他都可以
        bindHtml()
        // 2. 点击上一页
        prev.onclick = function () {
            // 2.1 判断能不能去上一页
            if (currentNum === 1) return

            // 2.2 调整页码
            currentNum--

            // 2.3 重新渲染  //  一点击 数据改变所有需要重新渲染      bindHtml() 不是  prev.onclick = function 本身 所以在点击事件里面
            bindHtml()
        }

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

            //3.2 调整页码使之加到最大
            currentNum++
            // 3.3重新渲染
            bindHtml()
        }
         // 4. 切换 每页 展示多少条  .onchange  改变事件
         select.onchange = function () {
            // 每次改变页码从第一开始
            currentNum = 1
            // 修改每页展示多少条
            pageSize = select.value - 0
            //重新渲染页面
            bindHtml()
         }
    </script>
</body>

</html>