js Web APIs

js Web APIs

DOM

获取元素

获取页面元素的方法:1、根据ID获取

​ 2、根据标签名获取

​ 3、通过HTML5新增的方法获取

​ 4、特殊元素获取

根据ID获取

使用getElementByld()方法可以获取带有ID的元素对象,返回值为一个元素对象

document.getElementById('id名');

使用getElementsByTagName获取某些元素,返回的是获取过来的元素对象的集合

// 返回的是 获取过来元素对象的集合 以伪数组的形式储存
        var lis = document.getElementsByTagName('li');
        console.log(lis);
// 返回的是 获取过来元素对象的集合 以伪数组的形式储存
        var lis = document.getElementsByTagName('li');
        console.log(lis);
        // 依次打印元素对象可以采用遍历的方式
        for(var i = 0; i < lis.length; i++)
        {
            console.log(lis[i]);
        }
根据标签名获取

可以获取某个元素(父元素)内部所有指定标签名的子元素

element.getElementsByTagName('标签名');

注意:父元素必须是单个对象(必须指明是哪一个元素对象)。获取的时候不包括父元素自己

// element.getElementsByTagName('ol');
        var ol = document.getElementsByTagName('ol');
        console.log(ol[0].getElementsByTagName('li'));
// 第二种方法
        var ol = document.getElementById('ol');
        console.log(ol.getElementsByTagName('li'));
通过HTML5新增的方法获取
document.getElementsByClassName('类名');//根据类名返回元素对象集合
<body>
    <div class="box">盒子</div>
    <div class="box">盒子</div>
    <div class="nav">
        <ul>
            <li>首页</li>
            <li>产品</li>
        </ul>
    </div>
    <script>
        // 1、getElementsByClassName 根据类名获得某些元素
        var boxs = document.getElementsByClassName('box');
        console.log(boxs);
    </script>
</body>
document.querySelector('选择器');//根据指定选择器返回第一个元素对象 切记里面的选择器需要加符号 类加.  id加#
// 2、querySelector 返回指定选择器的第一个对象
        var firstBox = document.querySelector('.box');
        console.log(firstBox);
document.querySelectorAll('选择器');//根据指定选择器返回 返回指定选择器的所有元素对象集合
获取特殊元素(body,html)

获取body元素

var bodyEle = document.body;//返回body对象

获取html元素

var htmlEle = document.documentElement;//返回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>
</head>
<body>
    <button id="btn">唐伯虎</button>
    <script>
        // 点击一个按钮,弹出对话框
        // 1、事件源 事件被触发的对象
        var btn = document.getElementById('btn');
        // 2、事件类型 如何触发 什么事件 比如鼠标点击(onclick)还是鼠标经过 还是键盘按下
        // 3、事件处理程序 通过一个函数赋值的方式完成
        btn.onclick = function(){
            alert('点秋香');
        }
    </script>
</body>
</html>

执行事件的步骤:1、获取事件源

​ 2、注册事件(绑定事件)

​ 3、添加事件处理程序(采取函数赋值形式)

常见的鼠标事件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i1u0zkBh-1650767316133)(js Web APIs.assets/CLRGBVN8V2NI%T5N_N1L.png)]

操作元素
改变元素内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JXhyVx7b-1650767316136)(js Web APIs.assets/QQ图片20220414125650.png)]

innerText

<!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>
        div,p{
            background-color: pink;
        }
    </style>
</head>
<body>
    <button>显示当前系统时间</button>
    <div>某个时间</div>
    <P>123</P>
    <script>
        // 当我们点击了按钮 div里面的文字会发生变化
        // 1、获取元素
        var btn = document.querySelector('button');
        var div = document.querySelector('div');
        // 2、注册事件
        btn.onclick = function(){
            div.innerText = getDate();
        }
        function getDate(){
            var date = new Date();
            var year = date.getFullYear();
            var month = date.getMonth() +1;
            var dates = date.getDay();
            var arr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六'];
            var day = date.getDay();
            return '今天是:'+ year+'年'+ month + '月' + dates + '日' + arr[day];
        }

        // 元素可以不用添加事件
        var p = document.querySelector('p');
        p.innerText = getDate();
    </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>
</head>
<body>
    <div></div>
    <script>
        // innerText和innerHTML的区别
        // 1、innerText不识别HTML标签 非标准 去除空格和换行
        var div = document.querySelector('div');
        div.innerText = '<strong>今天是:</strong> 2019';
        // 2、innerHTML W3C标准 识别html标签 保留空格和换行
        div.innerHTML = '<strong>今天是:</strong> 2019';
        // 这两个属性是可读写的 可以获取元素里面的内容
        var p = document.querySelector('p');
    </script>
</body>
</html>
常用元素的属性操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3szSyBm4-1650767316138)(js Web APIs.assets/QQ图片20220414133652.png)]

表单元素的操作属性

利用DOM可以操作如下表单元素的属性:

type, value, checked, selected, disabled

获得焦点:onfocus 失去焦点:onblur

<!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>
</head>
<body>
    <button>按钮</button>
    <input type="text" value="输入内容">
    <script>
        // 1、获取元素
        var btn = document.querySelector('button');
        var input = document.querySelector('input');
        // 2、注册事件处理程序
        btn.onclick = function(){
            // 表单里面的值通过value来进行修改
            input.value = '被点击了'
            // 如果想要某个表单被禁用 不能再点击 disabled 我们想要这个按钮 button 禁用
            // btn.disabled = true;
            this.disabled = true;
            // this指向的是事件函数的调用者
        }
    </script>
</body>
</html>
样式属性操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BJc6W3tC-1650767316139)(js Web APIs.assets/WS]N_`C7{AIA6Z5L56Q{XTG.png)]

注意:1、JS里面的样式采取驼峰命名法

​ 2、JS修改style样式操作,产生的是行内样式,css权重比较高

​ 3、className 会直接更改元素的类名,会覆盖原先的类名,如果想要保留原先的类名 使用多类名选择器

<!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>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
        }
    </style>
</head>
<body>
        <div></div>
        <script>
            // 1、获取元素
            var div = document.querySelector('div');
            // 注册事件 处理程序
            div.onclick = function(){
                // 里面的属性采用驼峰命名法
                this.style.backgroundColor = 'purple';
                this.style.width = '250px';
            }
        </script>
</body>
</html>

className修改元素类名更改样式

<!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>
        div {
            width: 200px;
            height: 200px;
            background-color: pink;
        }
        .change {
            width: 250px;
            height: 250px;
            background-color: skyblue;
            color: #fff;
        }
    </style>
</head>
<body>
    <div>文字</div>
    <script>
        var test = document.querySelector('div');
        test.onclick = function(){
            this.className = 'change';
            // 如果想要保留原先的类名
            this.className = 'first change';
        }
    </script>
</body>
</html>
排他思想

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WBfXo3F1-1650767316140)(js Web APIs.assets/2B[KZXNJBJ_NEXX{{GPB%A4.png)]

自定义属性的操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aex4C3pv-1650767316142)(js Web APIs.assets/QQ图片20220414164548.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KIrrCA4G-1650767316143)(js Web APIs.assets/%]T19$M50KAX41CP9EF9@C.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DHHYyJYX-1650767316145)(js Web APIs.assets/QQ图片20220414165353.png)]

H5自定义属性

自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据中

自定义属性获取是通过getAttribute(‘属性’)获取

但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tDfnGGht-1650767316146)(js Web APIs.assets/`ZTXBH%V4%NC90FS[SER.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w9IXNEs9-1650767316147)(js Web APIs.assets/D86UCI_J@0JB}8Q93TY7L2.png)]

如果自定义属性里面有多个 - 链接的单词,我们在获取的时候采取 驼峰命名法

H5新增的获取方法只能获取以data开头的自定义属性 并且ie11才开始支持,之前版本不兼容

节点操作
节点概述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3ae9kD98-1650767316148)(js Web APIs.assets/KR[Z1G$UZ_FD@7RD_13MS{M.png)]

节点层级

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZB1cp9r3-1650767316149)(js Web APIs.assets/[YH%TT7L]VD2M3FR1A{NDAF.png)]

父级节点

node.parentNode

**注意:**1、node.parentNode返回的是离元素最近的父节点

​ 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>
</head>
<body>
    <div class="box">
        <span class="erweima">x</span>
    </div>
    <script>
        // 1、父节点 parentNode
        var erweima = document.querySelector('.erweima');
        // 得到的是离元素最近的父级节点,如果找不到父节点就返回为空
        var box = erweima.parentNode; 
    </script>
</body>
</html>

子节点

node.chidNodes
//得到所有的节点包括元素节点 文本节点等
//判断得到的是什么节点
console.log(ul.childNodes[0].nodeType);
console.log(ul.childNodes[1].nodeType);

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zEFprlKm-1650767316150)(js Web APIs.assets/QQ图片20220414200405.png)]

只获取元素节点

parentNode.children

parentNode.children是一个只读属性,返回所有子元素节点。它只返回子元素节点,其余节点不反悔(重点掌握)

支持各种浏览器使用

获取第几个子节点

返回第一个子节点,找不到则返回null。也是返回所有节点

parentNode.firstChild;

返回第一个子节点,只返回元素节点

parentNode.firstElementChild

返回最后一个节点,找不到则返回null,也是返回所有节点

parentNode.lastChild

返回最后一行子元素节点

parentNode.lastElementChild

parentNode.fistElementChild和parentNode.lastElementNode有兼容性问题 IE9以上才支持

实际开发中 既没有兼容性问题又返回第一个子元素

解决方案:1、如果想要第一个子元素节点,可以使用parentNode.children[0];

​ 2、如果想要最后一个子元素节点,可以使用parentNode.children[ol.length - 1]

兄弟节点

返回当前元素的下一个兄弟节点,包含所有的节点

node.nextSibling

返回上一个兄弟节点,包含所有节点

node.previousSibling

返回当前元素下一个兄弟元素节点有兼容性问题IE9以上支持

node.nextElementSibling

返回上一个兄弟元素节点有兼容性问题IE9以上支持

node.previousElementSibling

如何解决兼容性问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B3uOsYkG-1650767316152)(js Web APIs.assets/QQ图片20220415134033.png)]

创建节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OnLNmZmA-1650767316153)(js Web APIs.assets/H$@8NPZRTI7KK`FEGVUSNA.png)]

添加节点

node.appendchild()方法将一个节点添加到指定父节点的子节点列表末尾。类似于CSS里面的after伪元素 后面追加元素

node.appendchild(child)

node.insertBefore()方法将一个节点添加到父节点的指定子节点前面。类似于css里面的before伪元素

node.insertBefore(child,指定元素)
<!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>
</head>
<body>
    <ul></ul>
    <script>
    // 1、创建节点元素节点
    var li = document.createElement('li');
    // 2、添加节点 node.appendChild(child)
    var ul = document.querySelector('ul');
    ul.appendChild(li);
    // 3、添加节点,在指定元素之前添加
    var lili = document.createElement('li');
    ul.insertBefore(lili,ul.children[0]);
    </script>
</body>
</html>

注意:想要页面中添加一个新元素:1、创造元素 2、添加元素

简单留言发布案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JiDdAAoI-1650767316154)(js Web APIs.assets/VZNL@7R%INWRWLQOZ]KX6B.png)]

<!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>
</head>
<body>
    <textarea name="" id=""></textarea>
    <button>发布</button>
    <ul>
        
    </ul>
    <script>
        // 1、获取元素
        var btn = document.querySelector('button');
        var text = document.querySelector('textarea');
        var ul = document.querySelector('ul');
        // 2、注册事件
        btn.onclick = function(){
            
            if(text.value == ''){
                alert('您没有输入内容');
                return false;
            }else{
                console.log(text.value);
                // 1、创建元素
                var li = document.createElement('li');
                // 先有li才能赋值
                li.innerHTML = text.value;
                // 2、添加元素
                // ul.appendChild(li);
                ul.insertBefore(li,ul.childeren[0]);
            }
        }
    </script>
</body>
</html>

删除节点

删除node节点中的子节点

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PRgQL8zS-1650767316155)(js Web APIs.assets/QQ图片20220415144722.png)]

<!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>
</head>
<body>
    <button>删除</button>
    <ul>
        <li>熊大</li>
        <li>熊二</li>
        <li>光头强</li>
    </ul>
    <script>
        // 1、获取元素
        var ul = document.querySelector('ul');
        var btn = document.querySelector('button');
        //2、删除元素
        //  ul.removeChild(ul.children[0]);
        //  3、点击按钮以此删除里面的孩子
        btn.onclick = function(){
            if(ul.children.length == 0)
            {
                this.disabled = true;
            }else{
                ul.removeChild(ul.children[0]);
            }
        }
    </script>
</body>
</html>
删除留言案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kb6LXmfj-1650767316156)(js Web APIs.assets/QQ图片20220415150111.png)]

复制节点(克隆节点)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-prKeybme-1650767316158)(js Web APIs.assets/QQ图片20220415150309.png)]

**注意:**1、如果括号参数为空或者为false,则是浅拷贝,即只克隆赋值节点本身,不克隆里面的子节点

​ 2、node.cloneNode(true);括号里面为true 深拷贝 复制标签并复制里面的内容

<!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>
</head>
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        // 1、node.cloenNode();
        var lili = ul.children[0].cloneNode(true);
        ul.appendChild(lili);
    </script>
</body>
</html>
动态生成表格

案例:1、准备数据

​ 2、创建行

​ 3、获取对象数据并将其给创建的单元格

<!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>
    </style>
</head>
<body>
    <table cellspacing="0">
        <thead>
            <tr>
                <th>姓名</th>
                <th>科目</th>
                <th>成绩</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            
        </tbody>
    </table>
    <script>
        // 1、先准备好学生数据
        var datas = [
            {
            name:'liu',
            subject:'javascript',
            score:100
        },{
            name:'li',
            subject:'javascript',
            score:99
        },
        {
            name:'lu',
            subject:'javascript',
            score:98
        }
    ];
    // 2、往tbody里面创建行:有几个人(通过数组长度)就创建几行
    var tbody = document.querySelector('tbody');
    for(var i = 0; i < datas.length; i++)
    {
        // 创建 tr行
        var tr = document.createElement('tr');
        tbody.appendChild(tr);
        // 行里面创建单元格 td 单元格数量取决于每个对象里面的属性个数
        for(var k in datas[i])
        {
            var td = document.createElement('td');
            // 把对象里面的数据给td
            td.innerHTML = datas[i][k];
            tr.appendChild(td);
        }
        // 3、创建有删除两字的单元格
        var td = document.createElement('td');
        td.innerHTML = '<a href="javascript:;">删除</a>';
        tr.appendChild(td);

    }
    // 4、删除操作
    var as = document.querySelectorAll('a');
    for(var i = 0; i < as.length; i++)
    {
        as[i].onclick = function(){
            // 点击a删除 当前a所在的行(链接的爸爸的爸爸)node.removeChild(child)
            tbody.removeChild(this.parentNode.parentNode);
        }
    }
    </script>
</body>
</html>

三种动态创建元素的区别

document.write()
element.innerHTML
document.createElement()

区别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ri99virG-1650767316159)(js Web APIs.assets/QQ图片20220415213225.png)]

//innerHTML数组形式拼接
var arr = [];
for (var i = 0; i <= 100; i++)
    {
        arr.push('<a href="#">百度</a>');
    }
inner.innerHTML = arr.join('');
DOM重点核心

主要有创建、增、删、改、查、属性操作、事件操作

创建:1、document.write

​ 2、innerHTML

​ 3、createElement

增:1、appendChild 在后面加

​ 2、insertBefore 在前面加

删:1、removeChild

改:主要修改dom的元素属性,dom元素的内容、属性,表单的值等

1、修改元素属性:src、href、title等

2、修改普通元素内容:innerHTML、innerText

3、修改表单元素:value、type、disable等

4、修改元素样式:style、className

查:主要获取查询dom的元素

1、DOM提供的API方法:getElementById、getElementsByTagName 古老用法不太推荐

2、H5提供的新方法:querySelector、querySelectorAll 提倡

3、利用节点操作获取元素:父(parentNode)、子(childNode)、兄(previousElementSibling、nextElementSibling)提倡

属性操作:主要针对于自定义属性

1、setAttribute: 设置dom的属性值

2、getAttribute:得到dom的属性值

3、removeAttribute移除属性

事件操作:给元素注册事件,采取事件源.事件类型=事件处理程序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vQKuw3L8-1650767316161)(js Web APIs.assets/QQ图片20220415214936.png)]

高级事件

注册事件

给元素添加事件,称为注册事件或者绑定事件

注册事件有两种方式:传统方式和方法监听注册方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CqOCKycO-1650767316162)(js Web APIs.assets/QQ图片20220416132422.png)]

唯一性:同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-teWPHOm1-1650767316163)(js Web APIs.assets/QQ图片20220416132906.png)]

addEventListener事件监听方式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mlAloX93-1650767316164)(js Web APIs.assets/QQ图片20220416133056.png)]

<!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>
</head>
<body>
    <button>传统注册方式</button>
    <button>事件监听方式</button>
    <script>
        var btns = document.querySelectorAll('button');
        // 2、事件侦听注册方式 里面的事件类型是字符串,需要加引号,不带on
        btns[1].addEventListener('click',function(){
            alert(22);
        })
        btns[1].addEventListener('click',function(){
            alert(33);
        })
    </script>
</body>
</html>
attachEven事件监听方式(了解)

![img](js Web APIs.assets/]UV_2N3NH3@VV8LL$}US.png)

注册事件兼容性解决方案(了解)

![img](js Web APIs.assets/FYVU[3VIX6L}09}XZK9{J.png)

删除事件
删除事件的方式

1、传统注册方式

eventTarget.onclick = null;

2、方法监听注册方式

eventTarget.removeEvenListener(type, listener[,useCapture]);
eventTarget.detachEvent(eventNameWithOn, callback);
<!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>
</head>
<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <script>
        var divs = document.querySelectorAll('div');
        divs[0].onclick = function(){
            alert(11);
            // 1、传统方式删除事件
            divs[0].onclick = null;
        }
        divs[1].addEventListener('click', fn);//里面的fn不需要调用加小括号

        function fn(){
            alert(22);
            divs[1].removeEventListener('click', fn);
        }
    </script>
</body>
</html>
删除事件兼容性解决方案(了解)

![img](js Web APIs.assets/7MOA]5CT8YPFS[5X7M0M.png)

DOM事件流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B0vSC7pA-1650767316165)(js Web APIs.assets/QQ图片20220416135655.png)]

DOM事件流分为3个阶段:1、捕获阶段

​ 2、当前目标阶段

​ 3、冒泡阶段

冒泡阶段:事件开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程

事件捕获:由DOM最顶层节点开始,然后逐级向下传播到最具体的元素接收的过程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wb7y7CN9-1650767316166)(js Web APIs.assets/CF33JLOA%Y}C}I7`0V4ZX3.png)]

4、实际开发中很少使用事件捕获,更关注事件冒泡

5、有些事件是没有冒泡的,比如onblur、onfocus、onmouseenter、onmouseleave

6、事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件。

事件对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ApZnHO0v-1650767316167)(js Web APIs.assets/DIN32TU@XDP@H7`A[T%F@YM.png)]

event是个形参,系统帮我们设定为事件对象,不需要传递实参过去

当我们注册事件时,event对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n6dhz063-1650767316168)(js Web APIs.assets/QQ图片20220416141951.png)]

事件对象的常见属性和方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DqV2N5eZ-1650767316169)(js Web APIs.assets/QQ图片20220416152612.png)]

阻止事件冒泡

事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点

事件冒泡本身的特性,会带来的坏处,也会带来好处,需要灵活掌握

方式:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6B8P42kR-1650767316170)(js Web APIs.assets/BV4{}PM3JWX8LL4NSZ0W7M.png)]

阻止事件冒泡的兼容性解决方案

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yVscUMIV-1650767316171)(js Web APIs.assets/QQ图片20220416154214.png)]

事件委托(代理、委派)

事件委托也成为时间代理,在jQuery里面称为事件委派

原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oHiudkEq-1650767316171)(js Web APIs.assets/LHTS0J_HXF%5@FODU1R]HJB.png)]

<!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>
</head>
<body>
    <ul>
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
    <script>
        // 事件委托的核心原理:给父节点添加侦听器,利用事件冒泡影响每一个子节点
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e){
            // e.target可以得到当前点击的对象
            e.target.style.backgroundColor = 'pink';
        })
    </script>
</body>
</html>
常用的鼠标事件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tDxoSf1o-1650767316172)(js Web APIs.assets/CLRGBVN8V2NI%T5N_N1L.png)]

禁止鼠标右键菜单

contexmenu禁止右键菜单

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ugzJHI9T-1650767316173)(js Web APIs.assets/NQ5PA$[A4}SJOVWFD9TC8Y.png)]

禁止鼠标选中(selectstart 开始选中)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a2D48jXM-1650767316175)(js Web APIs.assets/QQ图片20220416155931.png)]

鼠标事件对象

event对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象

MouseEvent和键盘事件对象KeyboardEvent

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qxysxrx9-1650767316176)(js Web APIs.assets/SUSONQP]SR7KLSLAM}]N0X.png)]

案例:跟随鼠标的天使

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Js6jsHtH-1650767316177)(js Web APIs.assets/QQ图片20220416161843.png)]

<!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>
        img {
            position: absolute;
            
        }
    </style>
</head>
<body>
    <img src="../images/4b84d997422c4f2381d1fb398d136a86.png" alt="">
    <script>
        var pic = document.querySelector('img');
        document.addEventListener('mousemove', function(e){
            // 1、只要鼠标移动1px 就会触发这个事件
            // 2、核心原理:每次鼠标移动,都会获得最新的鼠标坐标,把这个x和y坐标作为图片的top和left值就可以移动图片
            var x = e.pageX;
            var y = e.pageY;
            // 需要加上px单位
            pic.style.left = x - 50 + 'px';
            pic.style.top = y - 40 + 'px';
        })
    </script>
</body>
</html>
常用的键盘事件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aEilS1dR-1650767316179)(js Web APIs.assets/QQ图片20220416165116.png)]

注意1、如果使用addElementListener不需要加on

​ 2、onkeypress和前面2个的区别是,它不识别功能键,比如左右箭头,shift等

​ 3、三个事件的执行顺序是:keydown – keypress – keyup

键盘事件对象
键盘事件对象属性说明
keyCode返回该键的ASCII值

**注意:**onkeydown和onkeyup不区分字母大小写 onkeypress区分字母大小写

在实际开发中,更多使用keydown和keyup,能识别所有的键(包括功能键)

keypress不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值

模拟京东按键输入内容案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kZx0Q3JT-1650767316180)(js Web APIs.assets/QQ图片20220416171303.png)]

<!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>
</head>
<body>
    <input type="text">
    <script>
        var search = document.querySelector('input');
        document.addEventListener('keyup',function(e){
            // console.log(e.keyCode);
            if (e.keyCode === 83){
                search.focus();
            }
        })
    </script>
</body>
</html>
模拟京东快递单号查询案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-350euf4F-1650767316181)(js Web APIs.assets/2ZI1[G_(HIR0[`)]RN@%G8X.png)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ve5zTtTh-1650767316182)(js Web APIs.assets/73IS_M`8K4Q{0$UJ8AH[B4.png)]

keyup事件触发的时候,文字已经落入文本框里面了

BOM

BOM即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window。

window对象是浏览器的顶级对象,具有双重角色

1、它是JS访问浏览器窗口的一个接口

2、它是一个全局对象。定义在全局作用域中的变量、函数都会变成window对象的属性和方法。它在调用的时候可以省略window,前面学习的对话框都属于window对象方法,如aler()、prompt()等

注意:window下的一个特殊属性window.name

window常见事件

窗口加载事件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T6JvcExh-1650767316183)(js Web APIs.assets/QQ图片20220417135317.png)]

注意1、有了window.onload就可以把JS代码写到页面元素的上方,因为onload是等页面内容全部加载完毕再去执行处理函数。

​ 2、window.onload传统注册事件方式只能写一次,如果有多个,会以最后一个window.onload为准

​ 3、如果使用addEventListener则没有限制

提倡用addEventListener方式写

windou.addEventListener('load', function(){
    //内容
})

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JhHwskTF-1650767316184)(js Web APIs.assets/QQ图片20220417140239.png)]

load等页面内容全部加载完毕,包含页面dom元素 图片 flash css等

DOMContentLoaded是DOM加载完毕,不包含图片 flash css等就可以执行 加载速度比load更快一些

调整窗口大小事件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wOrpzomc-1650767316184)(js Web APIs.assets/QQ图片20220417141554.png)]

定时器

setTimeout()定时器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mRKG5exF-1650767316185)(js Web APIs.assets/QQ图片20220417142301.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KnsZCekB-1650767316186)(js Web APIs.assets/QQ图片20220417142500.png)]

5秒后自动关闭广告案例

案例分析:1、5秒之后,就把这个广告隐藏起来

​ 2、用定时器setTimeout

<!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>
</head>
<body>
    <img src="../images/QQ图片20220415101649.jpg" alt="" class="ad">
    <script>
        var ad = document.querySelector('.ad');
        setTimeout(function(){
            ad.style.display = 'none';
        },5000)
    </script>
</body>
</html>
停止setTimeout()定时器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sFzgeydB-1650767316186)(js Web APIs.assets/7HO}D0}@O}@E}{OIB1Q65X.png)]

setInterval()定时器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dBR0Dszu-1650767316187)(js Web APIs.assets/QQ图片20220417145114.png)]

<!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>
</head>
<body>
    <script>
        setInterval(function(){
            console.log('继续输出');
        }, 1000)
    </script>
</body>
</html>
倒计时案例

案例分析:1、这个倒计时是不断变化的,因此需要使用定时器来自动变化(setInterval)

​ 2、三个黑色盒子里面分别存放时分秒

​ 3、三个黑色盒子利用innerHTML放入计算的小时分钟秒数

​ 4、第一次执行也是间隔毫秒数,因此刚刷新页面会有空白

​ 5、最好采取封装函数的方式,这样可以先调用一次这个函数,防止刚开始刷新页面有空白问题

<!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>
        div span{
            display: inline-block;
            width: 40px;
            height: 40px;
            color: #fff;
            text-align: center;
            line-height: 40px;
            background-color: #333;
        }
    </style>
</head>
<body>
    <div>
        <span class="hour">1</span>
        <span class="minute">2</span>
        <span class="second">3</span>
    </div>
    <script>
        // 1、获取元素
        var hour = document.querySelector('.hour');
        var minute = document.querySelector('.minute');
        var second = document.querySelector('.second');
        var inputTime = +new Date('2022-4-17 18:00:00');
        // 开启定时器
        countDown();
        setInterval(countDown, 1000);
        function countDown(){
            var nowTime = +new Date();
            var times = (inputTime - nowTime) / 1000;
            var h = parseInt(times / 60 / 60 % 24);
            h = h < 10 ? '0' + h : h;
            hour.innerHTML = h;
            var m = parseInt(times / 60 % 60);
            m = m < 10 ? '0' + m : m;
            minute.innerHTML = m;
            var s = parseInt(times % 60);
            s = s < 10 ? '0' + s : s;
            second.innerHTML = s;
        }
    </script>
</body>
</html>
停止setInterval()定时器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Lyhbov9-1650767316188)(js Web APIs.assets/QQ图片20220417152000.png)]

<!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>
</head>
<body>
    <button class="begin">开启定时器</button>
    <button class="stop">停止定时器</button>
    <script>
        var begin = document.querySelector('.begin');
        var stop = document.querySelector('.stop');
        var timer = null;
        begin.addEventListener('click', function(){
            // timer设置为全局变量
            timer = setInterval(function(){
                console.log('你好');
            }, 1000);
        })
        stop.addEventListener('click', function(){
            clearInterval(timer)
        })
    </script>
</body>
</html>
发送短信案例

点击按钮后,该按钮60秒之内不能再次点击,防止重复发送短信

案例分析:1、按钮点击之后,会禁用disabled为true

​ 2、同时按钮里面的内容会变化,注意button里面的内容通过innerHTML修改

​ 3、里面的描述是有变化的,因此需要用到定时器

​ 4、定义一个变量,在定时器里面不断递减

​ 5、如果变量为0说明到了时间,我们需要停止定时器,并且复原按钮初始状态

<!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>
</head>
<body>
    手机号码:<input type="number"> <button>发送</button>
    <script>
        var btn = document.querySelector('button');
        var time = 10;//剩下的描述
        btn.addEventListener('click', function(){
            btn.disabled = true;
            var timer = setInterval(function(){
               if(time == 0)
               {
                    clearInterval(timer);
                    btn.disabled = false;
                    btn.innerHTML = '发送';
                    time = 10;
               }else{
                btn.innerHTML = '还剩下'+time+'秒';
                time--;
               }
            }, 1000)
        })
    </script>
</body>
</html>
this指向问题

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,一般情况下this的最终指向的是那个调用它的对象。

1、全局作用域或者普通函数中this指向全局对象window(注意定时器里面的this指向window)

2、方法中this指向调用方法的对象

3、构造函数中this指向构造函数的实例。

JS执行机制

JS是单线程语言

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i5UR1gvP-1650767316189)(js Web APIs.assets/QQ图片20220417164231.png)]

同步和异步

为了解决单线程造成的问题H5提出Web Worker标准,允许JS脚本创建多个线程。于是JS中出现了同步和异步

同步

前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。

异步

在做一件事情时,因为这件事情会花费很多时间,在做这件事的同时,可以处理其他事情。

本质区别:一条流水线上各个流程的执行顺序不同

同步任务

同步任务都是在主线程上执行,形成一个执行线

异步任务

JS的异步是通过回调函数实现的

一般而言,异步任务有以下三种类型:1、普通事件,如click、resize等

​ 2、资源加载,如load、error等

​ 3、定时器,包括setInterval、setTimeout等

异步任务相关回调函数添加到任务队列中(任务队列也称为消息队列)

执行机制

1、先执行执行栈中的同步任务

2、异步任务(回调函数)放到任务队列中

3、一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jG7L3ac5-1650767316191)(js Web APIs.assets/QQ图片20220417170719.png)]

location对象

window对象给我们提供了一个location属性用于获取或设置窗体的URL,并且可以用于解析URL。因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象。

URL

统一资源定位符是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EBR4ZDtd-1650767316192)(js Web APIs.assets/QQ图片20220418163354.png)]

location对象的属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EhKiw2al-1650767316193)(file:///C:\Users\sulli\Documents\Tencent Files\2524967263\Image\C2C\KD3}3{UJLWVKL}$]2VX`0Y0.png)]

href属性(常用)

<!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>
</head>
<body>
    <button>点击</button>
    <script>
        var btn = document.querySelector('button');
        btn.addEventListener('click', function(){
            location.href = 'http://www.itcast.cn';//跳转页面
        })
    </script>
</body>
</html>
5秒之后跳转页面案例

案例分析:1、利用定时器做倒计时效果

​ 2、时间到了,就跳转页面。使用location.href

<!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>
</head>
<body>
    <div></div>
    <script>
        var div = document.querySelector('div');
        var timer = 5;
        function tiaozhuan(){
            if(timer == 0){
                location.href = 'http://www.itcast.cn';
            }else{

                div.innerHTML = '您将在' + timer + '秒钟之后跳转到首页';
                timer--;
            }
        }
        tiaozhuan();
        setInterval(tiaozhuan, 1000);
    </script>
</body>
</html>
获取URL参数:不同页面参数传递案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jiXD3EeX-1650767316194)(js Web APIs.assets/QQ图片20220418172827.png)]

登录页面代码:

<!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>
</head>
<body>
    <form action="index.html">
        用户名:<input type="text" name="uname">
        <input type="submit" value="登录">
    </form>
</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>
</head>
<body>
    <div></div>
    <script>
        // console.log(location.search);
        // ?uname=andy
        // 1、先去掉?   substr('起始的位置',截取几个字符)
        var params = location.search.substr(1);
        console.log(params);
        // 2、利用+把字符串分割为数组 split('=')
        var arr = params.split('=');
        console.log(arr);
        var div = document.querySelector('div');
        // 3、把数据写入div中
        div.innerHTML = arr[1] + '欢迎您';
    </script>
</body>
</html>
location对象的方法
location对象方法返回值
location.assign()跟href一样,可以跳转页面(也称为重定向页面)记录浏览历史可以实现后退功能
location.replace()替换当前页面,因为不记录历史,所以不能后退页面
location.reload()重新加载页面,相当于刷新按钮或者f5 如果参数为true 强制刷新 ctrl+f5

navigator对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vzcjZr2x-1650767316196)(js Web APIs.assets/QQ图片20220418180119.png)]

history对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t9K01rfa-1650767316197)(js Web APIs.assets/QQ图片20220418180838.png)]

PC端网页特效

元素偏移量offset系列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LcJcy4cf-1650767316198)(js Web APIs.assets/@A7E2NA1TTPOW84]{{0VW2P.png)]

offset与style的区别

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZdXn87Nk-1650767316200)(js Web APIs.assets/QQ图片20220418182220.png)]

案例:获取鼠标在盒子内的坐标

案例分析:1、在盒子内点击,想要得到鼠标距离盒子左右的距离

​ 2、首先得到鼠标在页面中的坐标(e.pageX, e.pageY)

​ 3、其次得到盒子在页面中的距离(box.offsetLeft, box.offsetTop)

​ 4、用鼠标距离页面的坐标减去盒子在页面中的距离, 得到鼠标在盒子内的坐标。

5、如果想要移动一下鼠标,就要获取最新的坐标,使用鼠标移动事件mousemove

<!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>
        .box {
            width: 200px;
            height: 200px;
            background-color: pink;
            margin-top: 30px;
            margin-left: 65px;
        }
    </style>
</head>
<body>
    <div class="box"></div>
    <script>
        var box = document.querySelector('.box');
        box.addEventListener('mousemove', function(e){
        var y = e.pageY - box.offsetTop;
        var x = e.pageX - box.offsetLeft;
        box.innerHTML = 'x坐标是' + x + 'y坐标是' + y;
        })
    </script>
</body>
</html>
案例:模态框拖拽

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PLeflKrC-1650767316201)(js Web APIs.assets/QQ图片20220419132200.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3xXrIyGq-1650767316202)(js Web APIs.assets/7{_VZS$IZ22Q]VH]`CR3EL.png)]

案例:仿京东放大镜

案例分析:1、整个案例可以分为三个功能模块

​ 2、鼠标经过小图片盒子,黄色的遮挡层和大图片盒子显示,离开隐藏2个盒子功能

​ 3、黄色的遮挡层跟随鼠标功能

​ ①、把鼠标坐标给遮挡层不合适。因为遮挡层坐标以父盒子为准

​ ②、首先是获得鼠标在盒子的坐标

​ ③、之后把数值给遮挡层作为left和top值

​ ④、此时用到鼠标移动事件,但是还是在小图片盒子内移动

​ · ⑤、发现,遮挡层位置不对,需要再减去盒子自身高度和宽度的一半

​ ⑥、遮挡层不能超出小图片盒子范围

​ ⑦、如果小于0,就把坐标设置为0

​ ⑧、如果大于遮挡层最大的移动距离,就把坐标设置为最大的移动距离

​ ⑨、遮挡层的最大移动距离:小图片盒子宽度减去遮挡层盒子宽度

​ 4、移动黄色遮挡层,大图片跟随移动功能

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RRAcN9n1-1650767316203)(js Web APIs.assets/QQ图片20220419204757.png)]

元素可视区client系列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QyvyDhdp-1650767316205)(js Web APIs.assets/Y@`WDD55RA]OE@E}8FQ8GO3.png)]

立即执行函数

立即执行函数 (function() {})() 或者 (function() {}())

主要作用:创建一个独立的作用域,避免了命名冲突问题。不需要调用,自己立马执行函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QBlkxxU3-1650767316206)(js Web APIs.assets/COL0IEF5TMIPO7LQDV3}DDW.png)]

元素滚动scroll系列

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xmkHuVJY-1650767316207)(js Web APIs.assets/QQ图片20220419213657.png)]

3.2页面被卷去的头部

如果浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。当滚动条向下滚动时。页面上面被隐藏掉的高度,我们就称为页面被卷去的头部。滚动条在滚动时会触发onscroll事件。

案例:仿淘宝固定侧边栏

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6IYx4xZY-1650767316208)(js Web APIs.assets/QQ图片20220419214711.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OATjfOu7-1650767316209)(js Web APIs.assets/QQ图片20220419220855.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZxM9z513-1650767316210)(js Web APIs.assets/QQ图片20220420142830.png)]

<!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>
        .w{
            width: 1200px;
            margin: 10px auto;
        }
        .header{
            height: 150px;
            background-color: green;
        }
        .banner{
            height: 300px;
            background-color: blue;
        }
        .main{
            height: 3000px;
            background-color: purple;
        }
        .slider-bar{
            position: absolute;
            left: 50%;
            top: 300px;
            margin-left: 600px;
            width: 45px;
            height: 130px;
            background-color: pink;
        }
        span{
            position: absolute;
            bottom: 0;
            display: none;
        }
    </style>
</head>
<body>
    <div class="slider-bar">
        <span class="goBack">返回顶部</span>
    </div>
    <div class="header w">头部区域</div>
    <div class="banner w">banner区域</div>
    <div class="main w">主体部分</div>
    <script>
        // 1、获取元素
        var sliderbar = document.querySelector('.slider-bar');
        var banner = document.querySelector('.banner');
        var bannerTop = banner.offsetTop;//一定要写到滚动的外面
        var sliderbarTop = sliderbar.offsetTop -  bannerTop;
        var main = document.querySelector('.main');
        var goBack = document.querySelector('.goBack');

        var mainTop = main.offsetTop;
        // 2、页面滚动事件scroll
        document.addEventListener('scroll', function(){
            console.log(window.pageYOffset);
            // 3、当页面被卷去头部大于等于 300 此时侧边栏改为固定定位
            if(window.pageYOffset >= bannerTop){
                sliderbar.style.position = 'fixed';
                sliderbar.style.top = sliderbarTop + 'px';
            }else{
                sliderbar.style.position = 'absolute';
                sliderbar.style.top = '300px';
            }
            if(window.pageYOffset >= mainTop){
                goBack.style.display = 'block';
            }else{
                goBack.style.display = 'none';
            }
        })
    </script>
</body>
</html>
三大系列总结
三大系列大小对比作用
element.offsetWidth返回自身包括padding、边框、内容区的宽度,返回数值不带单位
element.clientWidth返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位
element.scrollWidth返回自身实际的宽度,不含边框,返回数值不带单位

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jbL5JOIk-1650767316211)(js Web APIs.assets/QQ图片20220420143717.png)]

主要用法:1、offset系列经常用于获得元素位置 offsetLeft offsetTop

​ 2、client经常用于获取元素大小 clientWidth clientHeight

​ 3、scroll经常用于获取滚动距离 scrollTop scrollLeft

mouseenter 和 mouseover的区别

mouseenter鼠标事件

1、当鼠标移动到元素上时就会触发mouseenter事件

2、类似mouseover,它们两者之间的差别是:mouseover鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter只会经过自身盒子触发。

3、之所以这样,是因为mouseenter不会冒泡

4、mouseenter搭配离开mouseleave同样不会冒泡

动画函数封装

动画实现原理

核心原理:通过定时器setInterval()不断移动盒子位置

实现步骤:1、获得盒子当前位置

​ 2、让盒子在当前位置加1个移动距离

​ 3、利用定时器不断重复这个操作

​ 4、加一个结束定时器的条件

​ 5、注意此元素需要添加定位,才能使用element.style.left

<!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>
        div {
            position: absolute;
            width: 100px;
            height: 100px;
            background-color: pink;
        }
    </style>
</head>
<body>
    <div></div>
    <script>
        // 动画原理
        var div = document.querySelector('div');
        var timer = setInterval(function(){
            if(div.offsetLeft >= 400){
                // 停止动画
                clearInterval(timer);
            }else{
                div.style.left = div.offsetLeft + 1 + 'px';
            }
            
        },30);
    </script>
</body>
</html>

动画函数简单封装

注意函数需要传递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>
        div {
            position: absolute;
            width: 100px;
            height: 100px;
            background-color: pink;
        }
        span{
            position: absolute;
            left: 0;
            top: 200px;
            display: block;
            width: 150px;
            height: 150px;
            background-color: purple;
        }
    </style>
</head>
<body>
    <div></div>
    <span></span>
    <script>
        // 简单动画函数封装obj目标对象 target 目标位置
        function animate(obj, target){
            var timer = setInterval(function(){
            if(obj.offsetLeft >= target){
                // 停止动画
                clearInterval(timer);
            }else{
                obj.style.left = obj.offsetLeft + 1 + 'px';
            }
            
        },30);
        }
        // 动画原理
        var div = document.querySelector('div');
        var span = document.querySelector('span');
        // 调用函数
        animate(div,300);
        animate(span,200);
    </script>
</body>
</html>

动画函数给不同元素记录不同定时器

如果多个元素都使用这个动画函数,每次都要var声明定时器。我们可以给不同的元素使用不同的定时器(自己专门用自己的定时器)

核心原理:利用Js是一门动态语言,可以很方便的给当前对象添加属性


        // 简单动画函数封装obj目标对象 target 目标位置
     //给不同的元素指定了不同的定时器
		//当不断点击按钮,启动动画时,元素的速度会越来越快,因为开启了太多的定时器
		//解决方案就是 让元素只有一个定时器执行
		
        function animate(obj, target){
            clearInterval(obj.timer);
            obj.timer = setInterval(function(){
            if(obj.offsetLeft >= target){
                // 停止动画
                clearInterval(obj.timer);
            }else{
                obj.style.left = obj.offsetLeft + 1 + 'px';
            }
            
        },30);
        }
        // 动画原理
        var div = document.querySelector('div');
        var span = document.querySelector('span');
        // 调用函数
        animate(div,300);
        animate(span,200);
 

缓动动画效果原理

缓动动画就是让元素运动速度有所变化,最常见的是让速度慢慢停下来

思路:1、让盒子每次移动的距离慢慢变小,速度就会慢慢落下来

​ 2、核心算法:(目标值-现在的位置)/ 10 作为每次移动的距离步长

​ 3、停止的条件:让当前盒子位置等于目标位置就停止定时器

<!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>
        div {
            position: absolute;
            width: 100px;
            height: 100px;
            background-color: pink;
        }
        span{
            position: absolute;
            left: 0;
            top: 200px;
            display: block;
            width: 150px;
            height: 150px;
            background-color: purple;
        }
    </style>
</head>
<body>
    <div></div>
    <span></span>
    <button>点击按钮动画移动</button>
    <script>
        // 简单动画函数封装obj目标对象 target 目标位置
        function animate(obj, target){
            clearInterval(obj.timer);
            obj.timer = setInterval(function(){
                // 步长值写到定时器的里面
                // 把步长值改为整数 不要出现小数的问题
                var step =Math.ceil(( target - obj.offsetLeft) / 10);
            if(obj.offsetLeft >= target){
                // 停止动画
                clearInterval(obj.timer);
            }else{
                // 缓动动画:把步长1 改为一个慢慢变小的值
                obj.style.left = obj.offsetLeft + step + 'px';
            }
            
        },30);
        }
        // 动画原理
        var div = document.querySelector('div');
        var span = document.querySelector('span');
        var btn = document.querySelector('button');
        // 调用函数
        animate(div,800);
        btn.addEventListener('click', function(){
            // 调用函数
            animate(span,500);
        })
    </script>
</body>
</html>

区别:1、匀速动画就是盒子当前的位置 + 固定的值

​ 2、缓动动画就是盒子当前的位置 + 变化的值((目标值-现在的值)/ 10)

动画函数多个目标值之间移动

可以让动画函数从800移动到500

当我们点击按钮时,判断步长是正值还是负值

1、如果是正值,则步长往大了取整

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>
        div {
            position: absolute;
            width: 100px;
            height: 100px;
            background-color: pink;
        }
        span{
            position: absolute;
            left: 0;
            top: 200px;
            display: block;
            width: 150px;
            height: 150px;
            background-color: purple;
        }
    </style>
</head>
<body>
    <div></div>
    <span></span>
    <button class="btn500">点击按钮动画移动500</button>
    <button class="btn800">800</button>
    <script>
        // 简单动画函数封装obj目标对象 target 目标位置
        function animate(obj, target, callback){
            clearInterval(obj.timer);
            obj.timer = setInterval(function(){
                // 步长值写到定时器的里面
                // 把步长值改为整数 不要出现小数的问题
                // var step =Math.ceil(( target - obj.offsetLeft) / 10);
                var step =( target - obj.offsetLeft) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
            if(obj.offsetLeft == target){
                // 停止动画
                clearInterval(obj.timer);
                if(callback)
                {
                    callback();
                }
            }
                // 缓动动画:把步长1 改为一个慢慢变小的值
                obj.style.left = obj.offsetLeft + step + 'px';
            
            
        },15);
        }
        // 动画原理
        var div = document.querySelector('div');
        var span = document.querySelector('span');
        var btn500 = document.querySelector('.btn500');
        var btn800 = document.querySelector('.btn800');
        // 调用函数
        animate(div,800);
        btn500.addEventListener('click', function(){
            // 调用函数
            animate(span,500);
        })
        btn800.addEventListener('click', function(){
            // 调用函数
            animate(span,800, function(){
                span.style.backgroundColor = 'red';
                console.log('nihao');
            });
        })
    </script>
</body>
</html>

动画函数封装到单独JS文件里面

因为以后经常使用这个动画函数,可以单独封装到一个JS文件里面,使用的时候引用这个JS文件即可

1、单独新建一个JS文件

案例:轮播图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pDOJn47B-1650767316212)(js Web APIs.assets/QQ图片20220421181834.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GePYn5vw-1650767316213)(js Web APIs.assets/QQ图片20220422143800.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HrgG1bcu-1650767316213)(js Web APIs.assets/QQ图片20220422143930.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-smyO3Nnw-1650767316214)(js Web APIs.assets/QQ图片20220422145412.png)]

节流阀

防止轮播图按钮连续点击造成播放过快

节流阀目的:当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发

核心实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数。

150px;
height: 150px;
background-color: purple;
}

点击按钮动画移动500 800 ```

动画函数封装到单独JS文件里面

因为以后经常使用这个动画函数,可以单独封装到一个JS文件里面,使用的时候引用这个JS文件即可

1、单独新建一个JS文件

案例:轮播图

[外链图片转存中…(img-pDOJn47B-1650767316212)]

[外链图片转存中…(img-GePYn5vw-1650767316213)]

[外链图片转存中…(img-HrgG1bcu-1650767316213)]

[外链图片转存中…(img-smyO3Nnw-1650767316214)]

节流阀

防止轮播图按钮连续点击造成播放过快

节流阀目的:当上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发

核心实现思路:利用回调函数,添加一个变量来控制,锁住函数和解锁函数。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值