dom&Bom_02Day


这里是学习webapi的dom,不是学h5与c3,为了不让代码太繁琐复杂,案例中的一些css我会写的很简单,体现出bom的知识点即可。

事件

什么是事件?用户点击了一下控件,或者键盘按下,鼠标经过等都是事件。

539

事件记得引号,事件一般都是小写。

540

后面的匿名函数,写成一个函数名也行。

<body>
    <button>
        点我
    </button>
    <script>
        let btn =document.querySelector("button")
        function demo() {
            alert("被点击了")
        }
        btn.addEventListener('click',demo)

    </script>
</body>

541

点击关闭图片案例

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

    span {
        display: inline-block;
        width: 20px;
        height: 20px;
        border: 1px solid black;
        vertical-align: top;
        line-height: 20px;
        text-align: center;
    }
</style>

<body>
    <div>
        <span>x</span>
        <img src="./6.jpg" alt="">

    </div>
    <script>
        let span = document.querySelector('span')
        let img = document.querySelector('img')
        span.addEventListener('click', function () {
            img.style.display = 'none'
        })
    </script>
</body>

事件类型有click,mouseenter,mouseleave,keydown,keyup,blur,focus,input等等等等,注意事件一般都是小写。

544

542

543

<!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>
        .main{
            border: 1px solid #ccc;
            width: 400px;
            height: 200px;
            margin: 0 auto;
            padding: 20px;
            
            /* background-color: pink; */
        }
        .head{
            height: 50px;
            /* background-color: blue; */
            z-index: 1;
            padding-left: 150px;
        }
        .name{
            font-size: 20px;
            color: red;
            line-height: 50px;
            height: 50px;
        }
        button{
            width: 80px;
        }
        .button{
            display: flex;
            justify-content: space-around;
            margin-top: 30px;
        }
    </style>
</head>
<body>
    <div class="main">
        <div class="head">
            <p><strong>随机点名</strong></p>
        </div>
        <div class="content">
            <span><strong>名字是:</strong></span>
            <span class="name">瑾年</span>
        </div>
        <div class="button">
            <button>开始</button>
            <button>结束</button>
        </div>
        
    </div>
    <script>
        let names=['瑾年','周东奇','张三','李四'];
        let name=document.querySelector('.name');
        let start=document.querySelector('button:first-child');
        let end=document.querySelector('button:last-child');
        let timer = 0
        let random = 0
        start.addEventListener('click',function(){
            // 定时器间歇函数,让名字随机变化
            timer = setInterval(function(){
                random=Math.floor(Math.random()*names.length)
                name.innerHTML=names[random];
            },100)
            names.splice(random,1)
            if(names.length==0){
                alert('没有名字了')
                clearInterval(timer)
            }
        })
        end.addEventListener('click',function(){
            clearInterval(timer);
        })
    </script>
</body>
</html>

注意,因为作用域的问题,timer和random需要在全局就声明好

老版本事件写法

545

<body>
    <button>点我</button>
    <script>
        let btn =document.querySelector('button')
        btn.onclick = function(){
            alert('我是老版本的写法')
        }
    </script>
</body>

小米搜索框

使用blur和focus事件。(失去焦点和取得焦点,这个焦点需要鼠标点击才有)

也可以用mouseleave和mouseenter,鼠标在上面就行

tips:属性值选择器,以前很少用

如此案例中的input[type=search]就是选择类型是search的input选择器

a[href]就是选择所有设置了href的超链接。

教程参考:https://blog.csdn.net/nicepainkiller/article/details/116132605
https://www.w3school.com.cn/css/css_selector_attribute.asp
<!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;
            box-sizing: border-box;
        }

        ul {

            list-style: none;
        }

        .mi {
            position: relative;
            width: 223px;
            margin: 100px auto;
            
        }

        .mi input {
            width: 223px;
            height: 48px;
            padding: 0 10px;
            font-size: 14px;
            line-height: 48px;
            border: 1px solid #e0e0e0;
            outline: none;
            transition: all .5s
        }

        .mi .search {
            border: 1px solid #ff6700;
        }

        .result-list {
            position: absolute;
            left: 0;
            top: 48px;
            width: 223px;
            border: 1px solid #ff6700;
            border-top: 0;
            background: #fff;
            display: none;
        }

        .result-list a {
            display: block;
            padding: 6px 15px;
            font-size: 12px;
            color: #424242;
            text-decoration: none;
        }

        .result-list a:hover {
            background-color: #eee;
        }
    </style>

</head>

<body>
    <div class="mi">
        <input type="search" placeholder="小米笔记本">
        <ul class="result-list">
            <li><a href="#">全部商品</a></li>
            <li><a href="#">小米11</a></li>
            <li><a href="#">小米10S</a></li>
            <li><a href="#">小米笔记本</a></li>
            <li><a href="#">小米手机</a></li>
            <li><a href="#">黑鲨4</a></li>
            <li><a href="#">空调</a></li>
        </ul>
    </div>
    <script>
        const input = document.querySelector('.mi input');
        const resultList = document.querySelector('.result-list');
        input.addEventListener('mouseenter', function () {
            resultList.style.display = 'block';
            input.classList.add('search');
        })
        input.addEventListener('mouseleave', function () {
            resultList.style.display = 'none';
            input.classList.remove('search');
        })



    </script>
</body>

</html>

微博输入案例

用户输入文字后,字数会自动统计输入了多少个。

546

<textarea placeholder="说点什么吧..." id="area" cols="30" rows="10" maxlength="200"></textarea>
<!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>
        .main {
            margin: 0 auto;
            width: 900px;
        }

        .botton {
            margin-left: 520px;
            font: bold 14px '宋体';
        }

        button {
            cursor: pointer;
            background-color: skyblue;
            border: none;
            color: aliceblue;
        }

        textarea {
            resize: none;
            border-radius: 10px;
        }
    </style>
</head>

<body>
    <div class="main">
        <textarea name="" id="" cols="82" rows="7" maxlength="200" placeholder="你今天有什么要分享给瑾年呢?"></textarea>
        <div class="botton">
            <span>0</span><span>/</span><span>200</span>
            <button>发布</button>
        </div>

    </div>

    <script>
        const textarea =document.querySelector('textarea')
        const button =document.querySelector('button')
        const text_num =document.querySelector('div span:first-child')
        // 看看有没有获取到,对选择器有点不自信
        // console.log(text_num)
        button.addEventListener('click',function(){
            alert('发布成功')
        })
        textarea.addEventListener('input',function(){
            text_num.style.color="red"
            text_num.innerHTML= textarea.value.length
            button.value= textarea.value.length
            console.log(button.value)
        })

    </script>
</body>

</html>

1-其中textarea可以设置placeholder和id和cols与rows以及maxlength,它还有一个css叫resize:none就可以禁止用户拖拉它的大小(默认是可以的)

2-input有一个readonly属性,可以只读,不可修改。

注意:

1-placeholder设置不生效的原因可能是,textarea标签之间有空格或者换行

错误:

1-在把textarea中的文字长度赋予span的时候,一直不生效,原来是把text_num.innerHTML写成了text_num.value,value是textarea,input等的属性,无法修改span的内容。把修改内容和属性记混了。

案例全选

547

1-当一个事件为false就把全选状态修改为false,使用return能提高性能,遇到false直接退出,减少后续的无用判断。

2-当同时给多个元素绑定相同事件,用for循环遍历。

548

其实就是多练习熟悉事件的语法,这些逻辑都很简单。

犯错:

1-层次不清晰,写着写着自己选择器记不得了,把获取对象后面的选择器写错,控制台也不报错,效果一直不生效。

2-注意循环中变量的声明,它们的作用域,哪些变量给了全局,哪些没有!

我自认为两个for循环可以使用一样的i,因为作用域不同,谁知道我原先定义了i为全局变量,一个bug能卡半小时找不出问题。也许这就是变量污染吧,也是立即使用函数诞生的原因。

3-所以说能使用不同变量,就使用不同的,不要以为自己对作用域很了解,最后把自己绕进去。

<!DOCTYPE html>

<html>

<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        table {
            border-collapse: collapse;
            border-spacing: 0;
            border: 1px solid #c0c0c0;
            width: 500px;
            margin: 100px auto;
            text-align: center;
        }

        th {
            background-color: #09c;
            font: bold 16px "微软雅黑";
            color: #fff;
            height: 24px;
        }

        td {
            border: 1px solid #d0d0d0;
            color: #404060;
            padding: 10px;
        }

        .allCheck {
            width: 80px;
        }
    </style>
</head>

<body>
    <table>
        <tr>
            <th class="allCheck">
                <input type="checkbox" name="" id="checkAll"> <span class="all">全选</span>
            </th>
            <th>商品</th>
            <th>商家</th>
            <th>价格</th>
        </tr>
        <tr>
            <td>
                <input type="checkbox" name="check" class="ck">
            </td>
            <td>小米手机</td>
            <td>小米</td>
            <td>¥1999</td>
        </tr>
        <tr>
            <td>
                <input type="checkbox" name="check" class="ck">
            </td>
            <td>小米净水器</td>
            <td>小米</td>
            <td>¥4999</td>
        </tr>
        <tr>
            <td>
                <input type="checkbox" name="check" class="ck">
            </td>
            <td>小米电视</td>
            <td>小米</td>
            <td>¥5999</td>
        </tr>
    </table>
    <script>
        //   给遍历存储所有复选框的checked状态伪数组的i
        let i = 0
        // 全选框后的全选/取消字体
        let span = document.querySelector('span')
        const all = document.querySelector('#checkAll')
        const cks = document.querySelectorAll('.ck')
        //   web计算机二级还是老写法,练一练
        all.onclick = function () {
            // 当全选框被点击后,子ck的checked全部变为true,再点击就全是false
            for (let i = 0; i < cks.length; i++) {
                cks[i].checked = all.checked
            }
            // 一定要放在这个函数里面,放外面的话,还没点就判断了,这个判断语句等于白写。
            if (all.checked === true) {
                span.innerHTML = '取消'
            } else {
                span.innerHTML = '全选'
            }
        }

        // 小按钮事件
        // 先遍历所有小按钮,添加监听器
        for (let j = 0; j < cks.length; j++) {
            console.log(cks[j])
            cks[j].addEventListener('click', function () {
                for (let g = 0; g < cks.length; g++) {
                    if (cks[g].checked == false) {
                        all.checked = false
                        span.innerHTML = '全选'
                        // 有一个是false,下面的小按钮就没必要再判断了
                        return
                    }
                }
                // 如果所有的按钮都是选中状态true,则让all.checked为true
                all.checked = true
                span.innerHTML = '取消'


            })

        }



    </script>
</body>

</html>

案例购物车加减案例

549

input的一个css,outline:none可以去除input获取焦点后的默认样式

outline:轮廓线

550

注意:

1-文本框表单等取过来的值和prompt一样都是字符串型的,记得转换。

2-这里的每次加1,可以把值从字符串转换成数字再加,也可以直接用++自增,因为自增可以隐式转换。(自增自减和比较运算符==,+=,-=都有隐士转换)

<body>
  <div>
    <input type="text" id="total" value="1" readonly>
    <input type="button" value="+" id="add">
    <input type="button" value="-" id="reduce" disabled>
    <script>
            const total = document.querySelector('#total')
            const add = document.querySelector('#add')
            const reduce = document.querySelector('#reduce')
            // 点加事件发生的事件函数
            add.addEventListener('click',function(){
                    total.value++
                    reduce.disabled =false
            })
            // 点减号发生的
            reduce.addEventListener('click',function(){
                total.value--
                if(total.value<=1){
                    reduce.disabled =true
                }
            })
    </script>
  </div>
</body>

高阶函数

551

高阶函数就是把函数当做值来对待

函数表达式

552

如let fn = function(){}和btn.onclick= function(){}都是函数表达式,是高阶函数的一种。

回调函数

553

当参数的那个函数就叫做回调函数。

环境对象

554

this叫做环境对象,它就是一个对象

555

上图第一个,因为fn()调用的全称是window.fn()所以this指向window

上图第二个因为btn对象调用了这个函数,所以this指向btn

排他思想(了解)

557

排他思想用于多个中只能存在一个的场景,如tab栏(只能选中一个),或者轮播图下面的小圆点(是哪张图片哪个圆点被选中,变css样式)

558

1-首先用for循环,把其他所有人干掉,让所有人都被生效这个样式

2-复活自己,所有人都不生效后,再给自己加上

<body>
    <button>第1个</button><button>第2个</button><button>第3个</button><button>第4个</button><button>第5个</button>
    <script>
        let btns = document.querySelectorAll('button')
        for (let i = 0; i < btns.length; i++) {
            btns[i].addEventListener('click', function () {
                // this.classList.add('pink')
                // 干掉所有人
                for (let j = 0; j < btns.length; j++) {
                    btns[j].classList.remove('pink')
                }
                // 复活我自己
                this.classList.add('pink')
            })
        }
    </script>
</body>

559

如上,五个按钮,选中谁,谁变粉色,先for循环让所有人都不生效粉色,然后给自己加上粉色的样式。

问题

其实一开始只会有一个生效,为了找到它,用for循环去遍历所有的,会浪费很多性能。

解决:

556

我们直接用document.querySelector找出哪个生效的,然后再去除即可。

然后再用this把事件加上即可。

注意

1-标签换行会有缺口,写在同一行就没有,如下

560

解决一:把标签写在一行,但是代码看起来凌乱

方法二:把父类font-size设置为0px,缺点是子类字体必须再设置font-size

参考https://baijiahao.baidu.com/s?id=1552352366285716&wfr=spider&for=pc

2-注意documen.querySelector和classList.add等的区别,一个是通过选择器选,一个是加类,一个带点,一个不带。如上图的pink类

综合案例tab栏

561

注意:

1-tab个数和页面个数必须一样,tab多了会没页面显示,页面多了会不隐藏,直接跳到下面去。

2-找选择器的时候,后代用空格隔开,如果要找的选择器有多个类,而且你需要用多个类找,需要把两个类连起来因为它们是兄弟。

思路:

js都好说,原先我的难点是四/多个内容页面,如何排在同一个地方?第一时间想到了绝对定位和浮动,因为它们脱标,再想想脱标也没用呀,照样会显示。

解决:

其实直接display:none就好了,因为是排他的,只有一个显示,所以可以多个内容在同一个地方。(其实就一个,其他的全部隐藏)

tips:

display:none不仅仅视觉上消失还脱标;visibility:hidden仅仅是视觉上消失,还占位。

<!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>
        .tab .active {
            background-color: pink;
            transform: scale(1.2);
        }
        a{
            display: none;
            width: 300px;
            height: 200px;
            border: 1px solid black;
        }
        /* 这个active和上面的tab active不一样,虽然都是给标签添加了active类名,但是生效的css不同 */
        .content .active{
            display: block;
        }
    </style>
</head>

<body>
    <div class="wraper">
        <div class="tab">
            <button class="active">第一个</button>
            <button>第二个</button>
            <button>第三个</button>
            <button>第四个</button>
            <button>第五个</button>
        </div>
        <div class="content">
            <div><a class="active">第一张</a></div>
            <div><a>第二张</a></div>
            <div><a>第三张</a></div>
            <div><a>第四张</a></div>
            <div><a>第五张</a></div>
        </div>

        
    </div>
    <script>
        let buttons = document.querySelectorAll('button')
        // 获取所有的a
        let as = document.querySelectorAll('.content a')

        for (let i = 0; i < buttons.length; i++) {
            buttons[i].addEventListener('click', function () {
                // 找出先前生效的,给它去除
                document.querySelector('.tab .active').classList.remove('active')
                // 让当前选中的生效
                this.classList.add('active')
                
                // 设置内容
                 // 找出先前生效的,给它去除
                 document.querySelector('.content .active').classList.remove('active')
                // 让当前选中的生效
                as[i].classList.add('active')

            })

        }

    </script>
</body>

</html>

文章作者: 瑾年
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 瑾年 !
评论
  目录