Web APIs --JavaScript学习笔记(总)(包括DOM、BOM)

DOM


1 基本语句

获取元素:

getElementByld:获取带有ID的元素对象

getElementByTagName():获取某类标签元素

getElementsByClassName(‘类名’),根据类名获取某些元素集合

querySelector(‘选择器’) 根据指定选择器返回第一个元素对象,里面选择器需要加符号 .class,#id

querySelectorAll(‘选择器’)返回指定选择器的所有对象集合

document.body //返回body元素对象

document.documentElement //返回html元素对象

元素属性值:

获取元素属性值:

element.属性 获取内置属性值

element.getAttribute(‘属性’) 自己添加的自定义属性,兼容性获取

注:规定自定义对象 data-… ,dataset是一个集合里面存放了所有以data开头的自定义属性

H5新增、ie11开始支持:element.dataset**.index** 或者element.dataset**[‘index’]** ,它只能获取data-开头的

修改元素属性值

element.属性=‘值’

element.setAttribute(‘属性’,‘值’)

移除属性

removeAttribute(‘index’);

鼠标事件

鼠标事件 触发条件
onclick 鼠标点击左键触发
onmouseover 鼠标经过出发
onmouseout 鼠标离开出发
onfocus 获得鼠标焦点触发
onblur 失去鼠标焦点出发
onmousemove 鼠标移动出发
mouseup 鼠标弹起触发
onmousedown 鼠标按下触发
mouseover和mouseenter

mouseenter鼠标事件

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

区别是:mouseover鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter只会经过自身盒子触发(子盒子不会触发(没有冒泡的概念))

mouseenter搭配鼠标离开mouseleave同样不会冒泡

操作元素

element.innerText:从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉

element.innerHTML:起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行

节点操作

利用父子兄节点关系获取元素,逻辑性强但兼容性较差

网页中所有内容都是节点(标签、属性、文本、注释等),在DOM中用node来表示。

一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)、和nodeValue(结点值)这三个基本属性。

  • 元素节点:nodeType为1,一般主要操作元素节点
  • 属性节点:nodeType为2
  • 文本节点:nodeType为3(文本节点包括文字、空格、换行等)
父节点:

node.parentNode:得到的是离元素最近的父节点,找不到父节点返回null

子节点:

parent.childNodes (标准)返回包含指定节点的子节点的集合,该集合为即时更新的集和。某一个就是.childNodes[i]

parent.children (非标准),但也得到各浏览器的支持

parentNode.firstChild返回第一个节点,不管是子节点还是元素节点,包括换行节点

parentNode.lastChild返回最后一个节点

parentNode.firstElementChild 返回第一个子元素节点,可能有兼容性问题

parentNode.lastElementChild返回最后一个子元素节点

实际开发中,没有兼容性的写法

xx.children[0]

xx.children[xx.children.length-1]

兄弟节点:

node.nextSibling:返回当前元素的下一个兄弟节点(包括换行),找不到则返回null

node.previousSibling:返回当前元素上一个兄弟节点(包括换行),找不到返回null

node.nextElementSibling:返回当前元素的下一个兄弟元素节点,ie9以上支持

node.previousElementSibling:返回当前元素的上一个兄弟元素节点,ie9以上支持

解决兼容性:自己封装函数

function getNextElementSibling(element){
    
    
    var el = element;
    while(el = el.nextSibling){
    
    
        if(el.nodeType === 1){
    
    
            return el;
        }
    }
    return null;
}
创建(元素)节点:

document.createElement(‘tagName’)

创建由tagName指定的HTML元素,因为这些元素原来不存在,根据需求动态生成

添加节点:

node.appendChild(child) :node是父级,child是子级

将一个节点添加到指定父节点的子节点列表末尾,即后面追加元素。类似于css里面的after伪元素,数组里的push。

node.insertBefore(child,指定元素)

将一个节点添加到父节点的指定节点前面。类似于css里面before伪元素

ul.insertBefore(lili,ul.children[0]);//实现了在ul.children[0]前面插入子节点lili
删除节点:

node.removeChild(child)

返回删除的节点

ul.removeChild(ul.children[0])
复制节点(克隆节点):

node.cloneNode()返回调用该方法节点的一个副本。

括号参数:空或者false是浅拷贝,只克隆复制节点本身不复制里面的内容

​ true深拷贝,复制标签里面的内容。

ul.children[0].cloneNode(true)
三种创建元素的区别:

1、document.write():直接将内容写进页面的内容流,但是文档执行完毕,它会导致页面全部重绘。

document.write('<div>123</div>')

2、element.innerHTML:将内容写入某个DOM节点,不会导致页面全部重绘

var xx = document.querySelector('.xx');
xx.innerHTML = '<a herf='#'>百度</a>'

3、document.createElement() :创建多个元素,效率比innerHTML高,因为innerHTML采用拼接的方法

var xx = document.querySelector('.xx');
var a = document.createElement('a');
xx.appendChild(a);

注:innerHTML创建多个元素,如果采用数组形式拼接(push)效率更高,结构稍复杂

createElement()创建多个元素,直接拼接效率高,但是比innerHTML采用数组形式拼接效率低,但是结构更加清晰。

2. 操作实例

2.1 按钮点击变色

五个按钮,点击某个按钮,其背景颜色变为粉色,其他按钮颜色默认

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v8q0BogP-1650003500754)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220408141239164.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>按钮1</button>
    <button>按钮2</button>
    <button>按钮3</button>
    <button>按钮4</button>
    <button>按钮5</button>
    <script>
        var btns = document.getElementsByTagName('button');
        for(var i = 0;i < btns.length ; i++){
    
    
            btns[i].onclick = function(){
    
    
                for(var j = 0; j< btns.length;j++){
    
    
                    btns[j].style.backgroundColor = '';
                }
                this.style.backgroundColor = 'pink';
            }
        }
    </script>
</body>
</html>

2.2 换肤效果

点击图片,页面背景改为当前的图片

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-33Ds5dB7-1650003500757)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220408110733486.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>
        *{
    
    
            margin:0;
            padding: 0;
        }
        body{
    
    
            background: url(D:/image/img1.jpg) no-repeat center top;
        }
        li{
    
    
            list-style: none;
        }
        .backChange{
    
    
            overflow: hidden;
            margin:100px auto;
            background-color: aquamarine;
            width: 410px;
            padding-top: 3px;
        }
        .backChange li{
    
    
            float: left;
            margin: 0 1 px;
            cursor: pointer;
        }
        .backChange img{
    
    
            /* display:block; */
            width: 100px;
            margin-left: 1px;
            /* height: 56.25px; */
        }
    </style>
</head>
<body>
    <ul class="backChange">
        <li><img src="D:\image\img1.jpg" alt=""></li>
        <li><img src="D:\image\img2.jpg" alt=""></li>
        <li><img src="D:\image\img3.jpg" alt=""></li>
        <li><img src="D:\image\img5.jpg" alt=""></li>
        <!-- <li><img src="D:\image\img5.jpg" alt=""></li> -->
    </ul>
    <script>
        var imgs = document.querySelector('.backChange').querySelectorAll('img');
        for(i = 0;i < imgs.length ;i++){
    
    
            imgs[i].onclick = function(){
    
    
                console.log(this.src);
                document.body.style.backgroundImage='url('+this.src+')';
            }
        }
    </script>
</body>
</html>

2.3 表格放置变色效果

鼠标经过一行变色,离开变回原色

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vfWK6Pgu-1650003500759)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220408113727117.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>
        table{
    
    
            width: 800px;
            margin: 100px auto;
            text-align: center;
            border-collapse: collapse;
            font-size: 14px;
        }
        thead tr{
    
    
            height: 30px;
            background-color: rgb(218, 114, 114);
        }
        tbody tr{
    
    
            height: 30px;
        }
        tbody td{
    
    
            border-bottom: 1px solid #999;
            font-size: 12px;
            color: rgb(255, 64, 0);
        }
        .bg{
    
    
            background-color: rgb(241, 138, 101);
        }
    </style>
</head>
<body>
    <table>
        <thead>
            <tr>
                <th>姓名</th>
                <th>班级</th>
                <th>年龄</th>
                <th>成绩</th>
                <th>排名</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1</td>
                <td>1</td>
                <td>1</td>
                <td>1</td>
                <td>1</td>
            </tr>
            <tr>
                <td>1</td>
                <td>1</td>
                <td>1</td>
                <td>1</td>
                <td>1</td>
            </tr>
            <tr>
                <td>1</td>
                <td>1</td>
                <td>1</td>
                <td>1</td>
                <td>1</td>
            </tr>
        </tbody>
    </table>
    <script>
        var trs = document.querySelector('tbody').querySelectorAll('tr');
        for(var i = 0;i<trs.length;i++){
    
    
            trs[i].onmouseover = function(){
    
    
                this.className='bg';
            }
            trs[i].onmouseout = function(){
    
    
                this.className='';
            }
        }
    </script>
</body>
</html>

2.4 表单全选与取消全选

要求一:全选按钮-所有选

要求二:单个按钮全部选-全选选中;单个按钮没有全部选-全选不选中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yBItS0I3-1650003500760)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220408144853661.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>
        table{
    
    
            width: 800px;
            margin: 100px auto;
            text-align: center;
            border-collapse: collapse;
            font-size: 14px;
        }
        thead tr{
    
    
            height: 30px;
            color: crimson;
            background-color: rgb(253, 209, 209);
        }
        tbody tr{
    
    
            height: 30px;
        }
        tbody td{
    
    
            border-bottom: 1px solid #999;
            font-size: 12px;
            color: rgb(255, 64, 0);
        }
    </style>
</head>
<body>
    <div class="wrap">
        <table>
            <thead>
                <tr>
                    <th>
                        <input type="checkbox" name="" id="cbAll">
                    </th>
                    <th>商品</th>
                    <th>价格</th>
                </tr>
            </thead>
            <tbody id="cb">
                <tr>
                    <td>
                        <input type="checkbox" name="" id="">
                    </td>
                    <td>iPhone</td>
                    <td>10000</td>
                </tr>
                <tr>
                    <td><input type="checkbox" name="" id=""></td>
                    <td>ipad</td>
                    <td>5000</td>
                </tr>
                <tr>
                    <td><input type="checkbox" name="" id=""></td>
                    <td>apple</td>
                    <td>10</td>
                </tr>
            </tbody>
        </table>
    </div>
    <script>
        var cbAll =document.getElementById('cbAll');
        var cb=document.getElementById('cb').getElementsByTagName('input');
        //要求一:全选-所有选
        cbAll.onclick=function(){
    
    
            console.log(this.checked);
            for(var i = 0 ; i < cb.length ; i++){
    
    
                cb[i].checked = this.checked;
            }
        }
        // 要求二:每一个都选了-全选;有一个没选-全选不选
        for(var i = 0 ; i < cb.length ; i++){
    
    
            cb[i].onclick = function(){
    
    
                var flag = true;
                for(var j = 0 ; j < cb.length ; j++){
    
    
                    if(!cb[j].checked){
    
    
                        flag = false;
                        break;
                    }
                }
                cbAll.checked = flag;
            }
        }
    </script>
</body>
</html>

2.5 tab栏切换

①点击首行菜单栏,点一个其背景颜色变色,其余原色

②点的内容显示相应的详细信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wWe83Iss-1650003500760)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220408163546207.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>
        .tab_list li{
    
    
            list-style: none;
            float: left;
            height: 39px;
            line-height: 39px;
            padding: 0 20px;
            text-align: center;
            cursor: pointer;
        }
        .tab_list .current{
    
    
            background-color: rgb(224, 191, 191);
            color: rgb(0, 0, 0);
        }
        /* .item_info{
            padding: 20px 0 0 20px;
        } */
        .item{
    
    
            display: none;
        }
    </style>
</head>
<body>
    <div class="tab">
        <div class="tab_list">
            <ul>
                <li class="current">商品介绍</li>
                <li>规格包装</li>
                <li>售后</li>
                <li>商品评价</li>
                <li>手机社区</li>
            </ul>

        </div>
        <div class="tab_con">
            <br><br>
            <div class="item" style="display: block;">
                商品模块介绍内容
            </div>
            <div class="item">
                规格包装内容
            </div>
            <div class="item">
                售后内容
            </div>
            <div class="item">
                评价内容
            </div>
            <div class="item">
                商品模块介绍内容
            </div>
        </div>
    </div>
    <script>
        var tab_list = document.querySelector('.tab_list');
        var lis = tab_list.querySelectorAll('li');
        var items = document.querySelectorAll('.item');

        for(var i=0 ; i<lis.length;i++){
    
    
            lis[i].setAttribute('index',i);
            lis[i].onclick = function(){
    
    
                for(var j=0;j<lis.length;j++){
    
    
                    lis[j].className = '';
                }
                this.className = 'current';
                var index = this.getAttribute('index');
                console.log(index)
                for(j = 0;j<items.length;j++){
    
    
                    items[j].style.display = 'none';
                }
                items[index].style.display = 'block';
            }
        }
    </script>
</body>
</html>

2.6下拉菜单

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IGWd0gJ2-1650003500762)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220408200844472.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>下拉菜单</title>
    <style>
        * {
    
    
            margin: 0;
            padding: 0;
        }
        
        li {
    
    
            list-style-type: none;
        }
        
        a {
    
    
            text-decoration: none;
            font-size: 14px;
        }
        
        .nav {
    
    
            margin: 100px;
        }
        
        .nav>li {
    
    
            position: relative;
            float: left;
            width: 80px;
            height: 41px;
            text-align: center;
        }
        
        .nav li a {
    
    
            display: block;
            width: 100%;
            height: 100%;
            line-height: 41px;
            color: #333;
        }
        .nav>li>a:hover{
    
    
            background-color: rgb(240, 193, 133);
        }
        .nav ul{
    
    
            display: none;
            position:absolute;
            top: 41px;
            left: 0;
            width: 100%;
            border-left: 1px solid #FECC5B;
            border-right: 1px solid #FECC5B;
        }
        .nav ul li{
    
    
            border-bottom:1px solid #FECC5B;
        }
        .nav ul li a:hover {
    
    
            background-color: #FFF5DA;
        }
    </style>
</head>
<body>
    <ul class="nav">
        <li>
            <a href="#">微博</a>
            <ul>
                <li><a href="#">私信</a></li>
                <li><a href="#">评论</a></li>
                <li><a href="#">@我</a></li>
            </ul>
        </li>
        <li>
            <a href="#">微博</a>
            <ul>
                <li><a href="#">私信</a></li>
                <li><a href="#">评论</a></li>
                <li><a href="#"> @我</a></li>
            </ul>
        </li>  
        <li>
            <a href="#">微博</a>
            <ul>
                <li><a href="#">私信</a></li>
                <li><a href="#">评论</a></li>
                <li><a href="#">@我</a></li>
            </ul>
        </li>
        <li>
            <a href="#">微博</a>
            <ul>
                <li><a href="#">私信</a></li>
                <li><a href="#">评论</a></li>
                <li><a href="#">@我</a></li>
            </ul>
        </li>
    </ul>
    <script>
        var nav = document.querySelector('.nav');
        var lis = nav.children;
        for(var i=0;i<lis.length;i++){
    
    
            lis[i].onmouseover = function(){
    
    
                this.children[1].style.display = 'block';
            }
            lis[i].onmouseout = function(){
    
    
                this.children[1].style.display='none';
            }
        }

    </script>
</body>
</html>

2.7简单版发布留言

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lvE2QaPU-1650003500763)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220409094424855.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>
        * {
            margin: 0;
            padding: 0;
        }
        
        body {
            padding: 100px;
        }
        
        textarea {
            width: 200px;
            height: 100px;
            border: 1px solid rgb(0, 73, 4);
            outline: none;
            resize: none;
        }
        
        ul {
            margin-top: 50px;
        }
        
        li {
            width: 300px;
            padding: 5px;
            background-color: rgb(248, 253, 179,0.5);
            color: rgba(238, 144, 20, 0.76);
            font-size: 14px;
            margin: 15px 0;
        }
    </style>
    
</head>
<body>
    <textarea name="" id=""></textarea>
    <button>发布</button>
    <ul>
        <!-- <li>133</li> -->
    </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.children[0]);
            }
        }
    </script>
</body>
</html>

2.8 接2.7删除某些留言

    <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 + "<a href='javascript:;'>删除</a>";
                // (2) 添加元素
                // ul.appendChild(li);
                ul.insertBefore(li, ul.children[0]);
                //删除元素
                var as = document.querySelectorAll('a');
                for(var i = 0 ; i<as.length ; i++){
    
    
                    as[i].onclick=function(){
    
    
                        ul.removeChild(this.parentNode);
                        console.log(this.parentNode);
                    }
                }
            }
        }
    </script>

3 DOM重点核心

DOM(Document Object Model文档对象模型)是W3C组织推荐的处理可拓展标记语言(HTML或XML)的标准编程接口。

我们获取过来的DOm元素是一个对象(Object)所以称为文档对象模型

dom操作:创建、增、删、改、查、属性、事件

创建:document.write()

​ innerHTML

​ creatElement()

增:appendChild

​ insertBefore

删:removeChild()

改:修改dom元素属性、元素内容、表单

查:DOM提供的API方法:getElementById、getElementByTagName

​ H5提供的新方法:querySelector、querySelectorAll

​ 利用节点获取元素:parentNode、Children、previousElementSibling、nextElementSibling

属性:setAttribute:设置属性值

​ getAttribute:得到属性值

​ removeAttribute:移除属性

事件:给元素注册事件:事件源.事件类型 = 事件处理程序

​ 各鼠标事件

4 事件高级

4.1 注册事件(绑定事件)

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

传统注册方式:特点注册事件的唯一性,同一个元素同一个事件只能设置一个处理函数,后面的会覆盖前面的处理函数

btn.onclick = funtion()

方法监听注册方式:addEventListener();IE9之前的IE不支持,可使用attachEvent()代替

4.1.1 addEventListener事件监听方式

同一个事件可以添加多个监听器

eventTarget.addEventListener(type, listener, useCapture)

btn.addEventListener('click', function(){
    
    alert(22);})
btn.addEventListener('click', function(){
    
    alert(33);})

type:事件类型,如click、mouseover,注意不带on,加引号

listener:事件处理函数,事件发生时调用该监听函数

useCapture:可选参数,布尔值,默认false

4.1.2 attachEvent事件监听方式

仅ie9以前的版本支持

eventTarget.attachEvent(eventNameWithOn , callback)

将指定的监听器注册到eventTarget(目标对象)上,对象触发指定事件后回掉函数被执行

eventNameWithOn:

callback:

btns[1].addEventListener('click', function() {
    
    alert(33);})//attachEvent ie9以前的版本支持

4.2 删除事件(解绑事件)

4.2.1 传统方式

eventTarget.onclick = null;

divs[0].onclick = function() {
    
    
	alert(11);
	divs[0].onclick = null;
}
4.2.2 方法监听注册方式

① eventTarget.removeEventListener(type, listener, useCapture)

divs[1].addEventListener('click', fn) // 里面的fn 不需要调用加小括号
function fn() {
    
    
    alert(22);
    divs[1].removeEventListener('click', fn);
}

② eventTarget.detachEvent(eventNameWithOn , callback)

divs[2].attachEvent('onclick', fn1);
function fn1() {
    
    
	alert(33);
	divs[2].detachEvent('onclick', fn1);
}

4.3 DOM事件流

事件流描述的时从页面中接收事件的顺序。事件发生时会在元素节点之间按照特定的顺序传播,这个过程叫做DOM事件流。

document—html—body---------div--------body—html—document

DOM事件流分三个阶段:

  1. 捕获阶段
  2. 当前目标阶段
  3. 冒泡阶段

①js代码只能执行捕获或冒泡其中一个阶段

②onclick和attachEvent只能得到冒泡阶段

③addEventListener(type, listener, useCapture),第三各参数如果是true则表示在捕获阶段调用事件处理程序。如果是false则是在冒泡阶段调用事件处理程序。

④实际更关注冒泡

⑤有些事件没有冒泡,如onblur,onfocus,onmouseenrter,onmouseleave

⑥事件冒泡有时会带来麻烦,有时会帮助

4.4 事件对象

4.4.1 概念和使用
var div = document.querySelector('div');
div.onclick = function(event){
    
    }//event就是一个事件对象,当形参来看

事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数

事件对象代表事件的状态,比如鼠标按键的状态、鼠标的位置、鼠标按钮的状态

这个事件对象我们可以自己命名 比如 event 、 evt、 e

事件对象也有兼容性问题 :ie678 通过 window.event 兼容性的写法 e = e || window.event;

4.4.2 事件对象的属性和方法:

e.target:返回触发事件的对象(元素),this返回绑定事件的对象

区别 : e.target 点击了那个元素,就返回那个元素 this 那个元素绑定了这个点击事件,那么就返回谁

this有个非常相似的属性currentTarget ie6-8不认识

事件对象的属性方法 说明
e.target 返回出发事件的对象 标准
e.srcElement 返回触发事件的对象 非标准ie6-8使用
e.type 返回事件的类型 比如click、mouseover不带on
e.cancelBubble 该属性阻止冒泡,非标准ie6-8使用
e.returnValue 该属性阻止默认事件(默认行为) 非标准ie6-8使用,比如不让链接跳转
e.preventDefault() 该属性阻止默认事件(默认行为) 标准,比如不让链接跳转
e.stopPropagatiom() 阻止冒泡 标准

4.5 阻止事件冒泡

e.stopPropagation(); // stop 停止 Propagation 传播

e.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡

var son = document.querySelector('.son');
son.addEventListener('click', function(e) {
	alert('son');
	e.stopPropagation(); // stop 停止  Propagation 传播
	e.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡
}, false);

4.6 事件委托(代理、委派)

冒泡特性会带来好处

事件委托原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。

例如给ul注册事件,利用事件对象的target来找到当前来找到当前点击的li,事件会冒泡到ul上,ul有注册事件,就会触发事件监听器。

    <ul>
        <li>冒泡</li>
        <li>冒泡</li>
        <li>冒泡</li>
        <li>冒泡</li>
    </ul>
    <script>
        var ul = document.querySelector('ul');
        ul.addEventListener('click', function(e){
    
    
            alert('冒泡泡');
            e.target.style.backgroundColor = 'pink';
        })
    </script>

4.7 鼠标事件(其他)

[第一部分鼠标事件]:

4.7.1禁止鼠标右键菜单contextmenu

contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单

document.addEventListener('contextmenu', function(e){
	e.preventDefault();
})
4.7.2 禁止鼠标选中(selectstart开始选中)
document.addEventListener('selectstart',function(e){
	e.preventDefault();
})
4.7.3 鼠标事件对象

鼠标事件对象MouseEvent,键盘事件对象KeyboardEvent

鼠标事件对象 说明
e.clientX 返回鼠标相对于浏览器窗口可视区的X坐标(滑动页面不影响)
e.clientY 返回鼠标相对于浏览器窗口可视区的Y坐标
e.pageX 返回鼠标相对于文档页面的X坐标,IE9+支持(滑动页面改变)
e.pageY 返回鼠标相对于文档页面的Y坐标,IE9+支持
e.screenX 返回鼠标相对于电脑频幕的X坐标
e.screenY 返回鼠标相对于电脑频幕的Y坐标
4.7.4案例-跟随鼠标移动的图片
<!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;
            height: 15px;

        }
    </style>
</head>
<body>
    <img src="D:\image\img4.jpg" alt="">
    <script>
        var pic = document.querySelector('img');
        document.addEventListener('mousemove', function(e){
            console.log(1);
            var x = e.pageX + 10;
            var y = e.pageY + 10;
            pic.style.left = x + 'px';
            pic.style.top = y + 'px';
        })
    </script>
</body>
</html>

4.8 键盘事件

4.8.1 基本事件
键盘事件 触发条件
onkeyup 某个键盘按键被松开时触发
onkeydown 某个键盘按键被按下时触发
onkeypress 某个键盘按键被按下时触发,但是不识别功能键如ctrl、shift、箭头等
    <script>
        // document.onkeyup = function(){
    
    
        //     console.log('弹起');
        // }
        document.addEventListener('keyup',function(){
    
    
            console.log('keyup弹起');
        })
        document.addEventListener('keydown',function(){
    
    
            console.log('keydown按下');
        })
        document.addEventListener('keypress',function(){
    
    
            console.log('keypress按下');
        })
    </script>

注意keydown和keypress顺序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Tj93dUrf-1650003500764)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220411155733001.png)]

4.8.2 keyCode属性

keyCode返回该键的ASCⅡ码值,从而判断用户按下了哪个键

keyup和keydown事件不区分字母大小写,a,A得到都是65

keypress区分大小写,a97,A65

4.8.3 案例-按键输入内容

按下键盘“s”,输入框被选中(焦点)

<body>
    <input type="text" name="" id="">
    <script>
        var search = document.querySelector('input');
        document.addEventListener('keyup',function(e){
            if(e.keyCode===83){
                search.focus();
            }
        })
    </script>
</body>
4.8.4 案例-输入内容自动显示大字号的内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IbjGX1Wh-1650003500765)(C:\Users\Administrator\Pictures\image-20220411172915857.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>
        * {
            margin: 0;
            padding: 0;
        }
        .search {
            position: relative;
            width: 100px;
            margin: 50px;
        }
        .con {
            display: none;
            position: absolute;
            top: -40px;
            width: 171px;
            border: 1px solid rgba(0, 0, 0, .2);
            box-shadow: 0 2px 4px rgba(0, 0, 0, .2);
            padding: 5px 0;
            font-size: 20px;
            line-height: 20px;
            color: #333;
        }
        .con::before {
            content: '';
            width: 0;
            height: 0;
            position: absolute;
            top: 28px;
            left: 18px;
            border: 8px solid #000;
            border-style: solid dashed dashed;
            border-color: #fff transparent transparent;
        }
    </style>
</head>
<body>
    <div class="search">
        <div class="con">空</div>
        <input type="text" placeholder="请输入您的快递单号" class="input">
    </div>
    <script>
        var con = document.querySelector('.con');
        var input = document.querySelector('.input');
        input.addEventListener('keyup',function(){
            if(input.value == ''){
                con.style.display = 'none';
            }
            else{
                con.style.display = 'block';    
                con.innerHTML = this.value; 
            }
        })
        //失去焦点盒子隐藏
        input.addEventListener('blur',function(){
            con.style.display = 'none';
        })
        input.addEventListener('focus',function(){
            if(this.value == ''){
                con.style.display = 'none';
            }
            else{
                con.style.display = 'block';
            }
        })
    </script>
</body>
</html>

BOM


1 BOM概述

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

BOM缺乏标准,最初是Netscape浏览器标准的 一部分。JavaScript语法标准化组织是ECMA,DOM的标准化组织是W3C。

DOM BOM
文档对象模型 浏览器对象模型
DOM就是把文档当作一个对象来看 BOM就是把浏览器当作一个对象来看
DOM顶级对象是document BOM顶级对象是window
DOM是W3C标准规范 BOM是浏览器厂商在各自浏览器上定义 的,兼容性较差
DOM主要学习的是操作页面元素 BOM学习的是浏览器窗口交互的一些对象

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

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

2、它是一个全局对象。定义在全局作用域中的变量、函数都会变成window对象的属性和方法

在调用的时候可以省略window

window下的一个特殊属性window.name,所以声明变量时不用name

2 window对象的常见事件

2.1窗口加载事件window.onload

window.onload = function(){
    
    }
或者
window.addEventListener("load",function(){
    
    });

当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS文件等)

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

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

​ 如果使用addEventListener则没有限制

DOMContentLoaded事件:

DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表,图片,flash等等

document.addEventListener('DOMContentLoaded',function(){
    
    });

2.2 调整窗口大小事件window.onresize

window.onresize = function(){
    
    }
window.addEventListener("resize",function(){
    
    })

只要窗口大小发生像素变化,就会触发这个事件

常利用这个事件完成响应式布局。window.innerWidth当前屏幕的宽度

<body>
    <script>
        window.addEventListener('load',function(){
            var div = document.querySelector('div');
            window.addEventListener('resize',function(){
                console.log(window.innerWidth);
                console.log('窗口变化');
                if(window.innerWidth <= 800){
                    div.style.display = 'none';
                }else{
                    div.style.display = 'block';
                }
            })
        })
    </script>
    <div></div>
</body>

3 定时器setTimeout()、setInterval()

3.1 setTimeout()

3.1.1使用
window.setTimeout(调用函数,[延迟的毫秒数]);//当设置的毫秒数到期后执行调用函数,这个window在调用时可省略
<script>
	function callback(){
		console.log('到时间了')
	}
	setTimeout(callback, 3000);
	setTimeout('callback()', 3000);//不提倡这样的写法
</script>

页面中可能有很多定时器,我们经常给定时器加标识符

var timer1 = setTimeout(callback, 3000);
var timer1 = setTimeout(callback, 5000);

*回调函数:需要等待时间,时间到了才去调用这个函数,因此称回调函数

3.1.2 案例-五秒关闭广告
<body>
    <img src="D:/image/img4.jpg" alt="" class="ad">
    <script>
        var ad = document.querySelector('.ad');
        setTimeout(function(){
            ad.style.display = 'none'
        },5000)
    </script>
</body>
3.1.3 clearTimeout()

clearTimeout()停止setTimeout()定时器

window.clearTimeout(timeoutID)

btn.addEventListener('click',function(){//给按钮添加结束定时器事件
	clearTimeout(timer);
})

①window可以省略

②参数里的定时器标识符不需要引号

3.3setInterval()

3.3.1使用
window.setInterval(回调函数,[间隔的毫秒数])//重复调用一个函数(每隔xx秒调用这个回调函数)
setInterval(function(){
	console.log('setInterval定时器');
},1000);
3.3.2 案例-倒计时

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sGBPcpIG-1650003500766)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220413111636203.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>倒计时</title>
    <style>
        .countDown{
            margin: 200px;
            height: 50px;
            width: 200px;
            background-color: rgb(240, 176, 176);
        }
        span{
            display: inline-block;
            width: 50px;
            height: 40px;
            background-color: rgb(230, 241, 132);
            text-align: center;
            line-height: 40px;
            margin: 5px;
        }
        .title{
            background-color: rgba(144, 229, 255, 0.973);
            position:absolute;
            margin: -25px 200px;
            color: burlywood;
        }
    </style>
</head>
<body>
    <div class="title">倒计时:距离2022-4-15 10:00:00还有</div>
    <div class="countDown">
        <span class="hour">1</span>
        <span class="minute">2</span>
        <span class="second">3</span>
    </div>
    <script>
        var hour = document.querySelector('.hour');
        var minute = document.querySelector('.minute');
        var second = document.querySelector('.second');
        var inputTime = +new Date('2022-4-15 10:00:00');
        countDown()//先调用一次这个函数,防止第一次刷新页面有空白
        setInterval(countDown,1000);
        function countDown(){
            var nowTime = +new Date();//+new Date返回的是毫秒数,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>
3.3.1 clearInterval()

使用:

var stop = document.querySelector('.stop');
stop.addEventListener('click',function(){
	clearInterval(timer);
})

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PTzzCJy7-1650003500766)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220413112258013.png)]

3.3.4 案例-发送短信案例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hHD8jfNz-1650003500767)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220413114316557.png)]

<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>

4 JS执行机制

4.1 JS是单线程

JavaScript的一大特点就是单线程,即一个时间只能做一件事

4.2 同步和异步

为解决单线程一些问题,利用多核CPU的计算能力,HTML5提出了Web Worker标准,允许JavaScript脚本创建多个线程。于是有了同步和异步。本质区别是这条流水线上的各个流程执行顺序不同。

异步即等待时间内可以做其他任务

如下:执行输出为:1 2 3

console.log(1);
setTimeout(function() {
    console.log(3);
}, 1000);
console.log(2);

定时器定时等待0秒也输出1 2 3

console.log(1);
setTimeout(function() {
    console.log(3);
}, 0);//等待0s,但是依旧后运行
console.log(2);

4.3执行过程

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

异步任务:JS异步是通过回调函数实现

  1. 普通事件:如click、resize等
  2. 资源加载:如load、errord等
  3. 定时器:包括setInterval、setTimeout等

执行过程:

  1. 先执行执行栈中的同步任务
  2. 异步任务(回调函数)放入任务队列中
  3. 执行栈中的同步任务执行完毕后,系统会一次读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈开始执行

事件循环:主线程不断重复获得任务、执行任务、再获取任务、再执行,这种机制被称作事件循环。

5 location对象

5.1 什么是location对象

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

5.2 URL

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

语法格式:

protocol://host[:post]/path/[?query]#fragment
https://www.......
组成 说明
protocol 通信协议,常用的http,ftp,maito等
host 主机(域名)
port 端口号,可选,省略时使用方案的默认端口,如http默认端口是80
path 路径 由零或多个’/'符号隔开的字符串,一般用来表示主机上的一个目录或文件地址
query 参数 以键值对的形式,通过&符号分隔开来
fragment 片段 #后面内容 常见于链接 锚点

5.3 location对象的属性

location对象属性 返回值
location.href 获取或设置整个URL
location.host 返回主机(域名)
location.port 返回端口号 如果未写返回空字符串
location.pathname 返回路径
location.search 返回参数
location.hash 返回片段 #后面内容 常见于链接 锚点

5.4 相关案例

5.4.1 5秒后跳转页面
<body>
    <button>点击立即跳转</button>
    <div></div>
    <script>
        var btn = document.querySelector('button');
        var div = document.querySelector('div');
        btn.addEventListener('click',function(){
            location.href = 'http://www.baidu.com';
        })
        var timer = 5 ; 
        setInterval(function(){
            if(timer == 0){
                location.href = 'http://www.baidu.com'
            }else{
                div.innerHTML = '您将在'+timer+'秒后跳转页面'
                timer--;
            }
        },1000);
    </script>
</body>
5.4.2 获取URL参数数据
image-20220413163128365 image-20220413163146314
<body>
    <form action="041304案例-index.html">
        用户名:<input type="text" name="uname">
        <input type="submit" value="登陆" name="" id="">
    </form>
</body>
<body>
    <div></div>
    <script>
        console.log(location.search);
        var params = location.search.substr(1);//去掉?uname=ss里面的?
        console.log(params);
        var arr = params.split('=');//利用等号把字符串分割成数组
        console.log(arr);
        //把数据写入div中
        var div = document.querySelector('div');
        div.innerHTML = arr[1]+'欢迎';
    </script>
</body>

5.5 location对象的方法

location对象的方法 返回值
location.assign() 与href一样,可以跳转页面(也称为重定向页面)
location.replace() 替换当前页面,因不记录历史,所以不能后退页面
location.reload() 重新加载页面,相当于刷新按钮或者f5,如果参数为true强制刷新ctrl+5

6 navigator对象

navigator对象包含有关浏览器的信息,属性如userAgent可以返回由客户机发送服务器的user-agent头部的值。

//判断用户用哪个终端打开页面
if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))){
	window.location.href = "";//手机
}
else{
	window.location.href = "";//电脑
}

7 history对象

window对象提供了一个history对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的URL。

history对象方法 作用
back() 可以后退功能
forward() 前进功能
go(参数) 前进后退功能,参数如果是1前进一个页面,如果是-1后退一个页面
<script>
    var btn = document.querySelector('button');
    btn.addEventListener('click',function(){
    
    
        history.forward();
    })
</script>


PC端网页特效

  • offset
  • client
  • scroll
  • 封装简单动画
  • 网页轮播图

1 offset元素偏移量

1.1概述

使用offset系列相关属性可以动态得到该元素的位置(偏移)、大小等。

  • 获得元素距离带有定位父元素的位置
  • 获得元素自身的大小(宽度高度)
  • 注意:返回的数值都不带单位
offset系列属性 作用
element.offsetParent 返回作为该元素带有定位的父级元素,如果父级都没有定位则返回body
element.offsetTop 返回元素相对带有定位父元素上方的偏移
element.offsetLeft 返回元素相对带有定位父元素左边框的偏移
element.offsetWidth 返回自身包括padding、边框、内容区的宽度,返回数值不带单位
element.offsetHeight 返回自身包括padding、边框、内容区的高度,返回数值不带单位

1.2 offset与style的区别

offset style
offset可以得到任意样式表中的样式值 style只能得到行内样式表中的样式值
offset系列获得的数值是没有单位的 style.width获得的是带单位的字符串
offsetWidth包含padding+border+width style.width获得不包括padding和border的值
offsetWidth等属性是只读属性,只能获取不能赋值 style.width是可读写属性,可以获取也可以赋值
结论:想要获取元素大小位置,用offset更合适 结论:想要给元素更改值,需要style改变

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

利用鼠标在页面内的坐标pageX、pageY,盒子距离左和上的距离offsetLeft、offsetTop,求出鼠标在盒子里面的坐标

image-20220413211417321
<!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{
    
    
            height: 300px;
            width: 300px;
            background-color: rgb(233, 201, 201,0.5);
            margin: 30px;
            text-align: center;
            line-height: 200px;
        }
    </style>
</head>
<body>
    <div class="box"></div>
    <script>
        var box = document.querySelector('.box');
        box.addEventListener('click',function(e){
    
    
            console.log(e.pageX);
            console.log(e.pageY);
            console.log(box.offsetLeft);
            console.log(box.offsetTop);
            var x = e.pageX - this.offsetLeft;
            var y = e.pageY - this.offsetTop;
            this.innerHTML = 'x坐标是'+x+'y坐标是'+y;
        })
    </script>
</body>
</html>

1.4 拖动模态框

点击链接,弹出登陆框,点关闭关闭登陆框,同时可以鼠标按下登陆会员位置,移动鼠标可以拖动登陆框。

image-20220414093705891
<!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>
        .login-header{
            width: 100%;
            height: 30px;
            text-align: center;
            font-size: 30px;
        }
        a {
            text-decoration: none;
            color: #000000;
        }
        .login{
            display: none;
            width: 512px;
            height: 250px;
            position: fixed;
            border: rgb(32, 237, 252) solid 2px;
            left: 50%;
            top: 40%;
            background: #d4a9a9;
            z-index: 9999;
            transform: translate(-50%, -50%);
            box-shadow: 0px 0px 20px #ddd;
        }
        .login-title{
            width: 100%;
            height: 40px;
            margin: 10px 0 0 0;
            text-align: center;
            cursor: move;
            font-size: 20px;
        }
        .close-login{
            position: absolute;
            border-radius: 50%;
            text-align: center;
            line-height: 40px;
            right: -30px;
            top: -30px;
            background: rgba(0, 225, 255,0.3);
            font-size: 14px;
            width: 40px;
            height: 40px;
            border: rgba(122, 220, 250, 0.3) solid 1px;
        }
        .login-input-content {
            margin-top: 20px;
        }
        .login-input {
            overflow: hidden;
            /* margin: 0px 0px 20px 0px; */
        }
        .login-input label {
            margin: 0 0 0 15px;
            float: left;
            width: 90px;
            padding-right: 10px;
            text-align: right;
            line-height: 35px;
            height: 35px;
            font-size: 18px;
        }
        .login-input .list-input {
            float: left;
            line-height: 35px;
            height: 35px;
            width: 350px;
            border: #ffd903 1px solid;
            text-indent: 5px;
        }
        .login-button {
            width: 50%;
            margin: 30px auto 0px auto;
            line-height: 40px;
            font-size: 14px;
            border: #fa6c6c 1px solid;
            text-align: center;
        }
        /* .login-button a {
            display: block;
        } */
        .login-bg {
            display: none;
            width: 100%;
            height: 100%;
            position: fixed;
            top: 0px;
            left: 0px;
            background: rgba(0, 0, 0, .3);
        }
    </style>
</head>
<body>
    <div class="login-header"><a href="javascript:;" id="link">点击弹出登录框</a></div>
    <div class="login" id="login">
        <div class="login-title" id="title">登陆会员
            <span><a class="close-login" id="closeBtn" href="Javacript:void(0);">关闭</a></span>
        </div>
        <div class="login-input-content">
            <div class="login-input">
                <label>用户名:</label>
                <input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input">
            </div>
            <br>
            <div class="login-input">
                <label>登陆密码:</label>
                <input type="password" placeholder="请输入登陆密码" name="info[password]" id="password" class="list-input">
            </div>
        </div>
        <div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登陆会员</a></div>
    </div>
    <!-- 遮盖层 -->
    <div id="bg" class="login-bg"></div>

    <script>
        var login = document.querySelector('.login');
        var mask = document.querySelector('.login-bg');
        var link = document.querySelector('#link');
        var closeBtn = document.querySelector('#closeBtn');
        var title = document.querySelector('#title');
        link.addEventListener('click',function(){
            mask.style.display = 'block';
            login.style.display = 'block';
        });
        closeBtn.addEventListener('click',function(){
            mask.style.display = 'none';
            login.style.display = 'none';
        })
        title.addEventListener('mousedown',function(e){
            var x = e.pageX - login.offsetLeft;
            var y = e.pageY - login.offsetTop;
            document.addEventListener('mousemove',move);
            function move(e){
                login.style.left = e.pageX - x + 'px';
                login.style.top = e.pageY - y + 'px';
            }
            document.addEventListener('mouseup',function(){
                document.removeEventListener('mousemove',move);
            })
        })
    </script>
</body>
</html>

2 client元素可视区

使用client系列相关属性来获取元素可视区的相关信息。动态得到元素边框大小、元素大小

client 宽度 和我们offsetWidth 最大的区别就是 不包含边框

client系列属性 作用
element.clientTop 返回元素上边框大小
element.clientLeft 返回元素左边框大小
element.clientWidth 返回自身包括padding、内容区宽度,不含边框,返回数值不带单位
element.clientHeight 返回自身包括padding、内容区高度,不含边框,返回数值不带单位

2.1 立即执行函数

立即执行函数,不需要调用,立马能够自己执行的函数。

立即执行函数最大的作用就是 独立创建了一个作用域, 里面所有的变量都是局部变量 不会有命名冲突的情况。

(function(){})()
//或者
(function(){}());
(function(a,b){
    
    
    console.log(a + b);
})(1,2);//两个立即执行函数前一个最后一定要有分号

(function(a,b){
    
    
    console.log(a+b);
}(2,3));

2.2 物理像素比dpr

pc端物理像素比为1,一些移动端如iphone678,dpr为2

var dpr = window.devicePixelRatio || 1

2.3 pageshow

页面发生变化时,重新设置。

load事件触发:a标签超链接、F5或刷新按钮(强制刷新)、前进后退按钮

一些浏览器如火狐,特点往返缓存,村村中保存着页面数据、DOM和JavaScript状态,实际上是整个页面都保存在内存里。所以,此时后退按钮不会刷新页面。

pageshow事件在页面显示时触发,无论页面是否来自缓存。在重新加载页面中,pageshow会在load事件触发后触发;根据事件对象中的persisted来判断是否是缓存中的页面触发的pageshow事件。

注意:这个事件给window添加。

window.addEventListener('pageshow',function(e){
    
    
    //e.persisted返回的true就是从缓存取出来的页面
	alert('11');
})
window.addEventListener('load',function(){
    
    
	alert('11');
})

3 元素滚动scroll

动态得到元素大小、滚动距离等。(内容大小,如盒子内文字超出盒子范围,返回内容的实际属性)

scroll系列属性 作用
element.scrollTop 返回被卷上去的上侧距离,返回数值不带单位
element.scrollLeft 返回被卷上去的左侧距离,返回数值不带单位
element.scrollWidth 返回自身的实际宽度,不含边框,返回数值不带单位
element.scrollHeight 返回自身的实际高度,不含边框,返回数值不带单位

3.1 onscroll事件

页面被卷去的头部,滚动条向下滚动,页面上被隐藏的高度,称页面被卷去的头部。滚动条在滚动时会触发onscroll事件。

div.addEventListener('scroll',function(){
    
    
    console.log(div.scrollTop)
})

3.2 案例-侧边栏定位

页面滚动到一定位置,出现返回顶部操作

*页面被卷去的头部:可以通过window.pageYOffset获得,被卷去的左侧window.pageXOffset

*元素被卷去的头部element.scrollTop

<!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>
        .slider-bar {
            position: absolute;
            left: 50%;
            top: 300px;
            margin-left: 600px;
            width: 45px;
            height: 130px;
            background-color: pink;
        }
        .w {
            width: 1200px;
            margin: 10px auto;
        }
        .header {
            height: 150px;
            background-color: rgb(231, 203, 231);
        }
        .banner {
            height: 250px;
            background-color: rgb(198, 236, 252);
        }
        .main {
            height: 1000px;
            background-color: rgb(211, 223, 188);
        }
        span {
            display: none;
            position: absolute;
            bottom: 0;
        }
    </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>
        var sliderbar = document.querySelector('.slider-bar');
        var banner = document.querySelector('.banner');
        var main = document.querySelector('.main');
        var goBack = document.querySelector('.goBack');
        var sliderbarTop = sliderbar.offsetTop - banner.offsetTop;
        document.addEventListener('scroll',function(){
            if(window.pageYOffset > banner.offsetTop){
                sliderbar.style.position = 'fixed';
                sliderbar.style.top = sliderbarTop + 'px';
            }
            else{
                sliderbar.style.position = 'absolute';
                sliderbar.style.top = '300px';
            }
            if(window.pageYOffset > main.offsetTop){
                goBack.style.display = 'block';
            }
            else{
                goBack.style.display = 'none';
            }
        })
    </script>
</body>
</html>

3.3 页面被卷去的头部兼容性解决方法

因为兼容性问题,所以被卷去的头部通常有如下几种写法:

  1. 声明了DTD,使用document.documentElement.scrollTop
  2. 未声明DTD,使用document.body.scrollTop
  3. 新方法window.pageYOffset和window.pageXOffset,ie9开始支持
function getScroll(){
    
    
	return{
    
    
		left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0 ,
		top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0 
	};
}

//使用
getScroll().left

3.4 三大系列总结

  1. offset系列用于获得元素位置 offsetLeft、offsetTop
  2. client常用于获取元素大小clientWidth、clientHeight
  3. scroll常用于获得滚动距离scrollTop、scrollLeft
  4. 注意页面滚动的距离通过window.pageXOffset获得

4 动画函数封装

4.1动画实现原理

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

  1. 获得盒子当前位置
  2. 让盒子在当前位置加上1个移动距离
  3. 利用定时器不断重复这个操作
  4. 加一个结束定时器的条件
  5. 注意此元素需要添加定位, 才能使用element.style.left
    <script>
        //动画元素需要添加定位position
        var div = document.querySelector('div');
        var timer = setInterval(function(){
            if(div.offsetLeft > 400){
                clearInterval(timer)
            }
            div.style.left = div.offsetLeft + 5 +'px';
        },30);
    </script>

4.2 动画函数封装

需要传递两个参数:动画对象移动的距离

<button>点击开始小方块</button>
<div></div>
<span></span>
<script>
    //动画元素需要添加定位position
    var div = document.querySelector('div');
    var span = document.querySelector('span');
    var btn = document.querySelector('button');
    animate(div,300);
    btn.addEventListener('click',function(){
        animate(span,200);
    })
    function animate(obj, target){
        // 当我们不断的点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器
        // 解决方案就是 让我们元素只有一个定时器执行
        // 先清除以前的定时器,只保留当前的一个定时器执行
        clearInterval(obj.timer);
        obj.timer = setInterval(function(){
            if(obj.offsetLeft > target){
                 clearInterval(obj.timer)
             }
             obj.style.left = obj.offsetLeft + 5 +'px';
         },30);
     }        
</script>

4.3 缓动动画

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

  1. 让盒子每次移动的距离慢慢变小,速度慢慢落下来
  2. 核心算法:(目标值-现在位置)/10 作为每次移动的步长
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)
        }
        obj.style.left = obj.offsetLeft + step +'px';
    },15);
}

若添加回掉函数,回调函数写在定时器结束里面

4.4 实例-缓动动画

鼠标移动到箭头位置,展开问题反馈盒子

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RP3qkNDB-1650003500769)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220415103855591.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AZjfIYfG-1650003500769)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220415103810021.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>
        .sliderbar {
    
    
            position: fixed;
            right: 0;
            bottom: 100px;
            width: 40px;
            height: 40px;
            text-align: center;
            line-height: 40px;
            cursor: pointer;
            color: rgb(248, 116, 116);
        }
        .con {
    
    
            position: absolute;
            left: 0;
            top: 0;
            width: 200px;
            height: 40px;
            background-color: rgb(240, 193, 240);
            z-index: -1;
        }
    </style>
    <script src="animate.js"></script>
</head>
<body>
    <div class="sliderbar">
        <span></span>
        <div class="con">问题反馈</div>
    </div>
    <script>        
        var sliderbar = document.querySelector('.sliderbar');
        var con = document.querySelector('.con');
        sliderbar.addEventListener('mouseenter',function(){
    
    
            animate(con,-160,function(){
    
    
                sliderbar.children[0].innerHTML = '→';
            });
        })
        sliderbar.addEventListener('mouseleave',function(){
    
    
            animate(con,0,function(){
    
    
                sliderbar.children[0].innerHTML = '←';
            });
        })
    </script>
</body>
</html>

5 常见网页特效案例

j.timer)
}
obj.style.left = obj.offsetLeft + 5 +‘px’;
},30);
}


#### 4.3 缓动动画

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

1. 让盒子每次移动的距离慢慢变小,速度慢慢落下来
2. 核心算法:(目标值-现在位置)/10  作为每次移动的步长

```javascript
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)
        }
        obj.style.left = obj.offsetLeft + step +'px';
    },15);
}

若添加回掉函数,回调函数写在定时器结束里面

4.4 实例-缓动动画

鼠标移动到箭头位置,展开问题反馈盒子

[外链图片转存中…(img-RP3qkNDB-1650003500769)]

[外链图片转存中…(img-AZjfIYfG-1650003500769)]

<!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>
        .sliderbar {
    
    
            position: fixed;
            right: 0;
            bottom: 100px;
            width: 40px;
            height: 40px;
            text-align: center;
            line-height: 40px;
            cursor: pointer;
            color: rgb(248, 116, 116);
        }
        .con {
    
    
            position: absolute;
            left: 0;
            top: 0;
            width: 200px;
            height: 40px;
            background-color: rgb(240, 193, 240);
            z-index: -1;
        }
    </style>
    <script src="animate.js"></script>
</head>
<body>
    <div class="sliderbar">
        <span></span>
        <div class="con">问题反馈</div>
    </div>
    <script>        
        var sliderbar = document.querySelector('.sliderbar');
        var con = document.querySelector('.con');
        sliderbar.addEventListener('mouseenter',function(){
    
    
            animate(con,-160,function(){
    
    
                sliderbar.children[0].innerHTML = '→';
            });
        })
        sliderbar.addEventListener('mouseleave',function(){
    
    
            animate(con,0,function(){
    
    
                sliderbar.children[0].innerHTML = '←';
            });
        })
    </script>
</body>
</html>

5 常见网页特效案例

猜你喜欢

转载自blog.csdn.net/weixin_44400887/article/details/124193845