JavaScript 详细学习笔记4

JavaScript 详细学习笔记4

1. 事件高级

1.1 注册事件

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

1.1.1 传统注册事件
  • 利用on开头的事件 比如onclick
  • 特点:注册事件的唯一性–>同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数
1.1.2 addEventListener方法监听注册事件

document.addEventListener(event,function,useCapture)

event:描述事件名称的字符串;
function:事件发生后需要执行的操作;
useCapture:可选,布尔值,指定事件是否在捕获阶段还是冒泡阶段执行,true->捕获阶段执行,false->冒泡阶段执行,默认false;

  • W3C标准 推荐方式
  • addEventListener() 它是一个方法
  • IE9以前的IE不支持此方法,可使用attachEvent()代替
  • 同一个元素同一事件可以注册多个监听器
  • 按照注册顺序依次执行
  • eventTarget.addEventListener(type,listener[ , useCapture]):将指定的监听器注册到eventTarget(目标对象)上,就会执行事件处理函数
    • type:事件类型字符串,比如 click,mouseover,注意这里不带on
    • listener:事件处理函数,事件发生时,会调用该监听函数
    • useCapture:可选参数,是一个布尔值,默认是false
1.1.3 attachEvent 事件监听方式

eventTarget.attachEvent(eventNameWithOn,callback):指将指定的监听器注册到eventTarget(目标对象)上,当该对象触发指定的事件时,指定的回调函数将会被执行

  • eventNameWithOn:事件类型字符串,比如onclick,onmouseover ,这里要带on
  • callback:事件处理函数,当目标函数被触发时,回调函数被调用
<body>
    <button>传统注册事件</button>
    <button>方法监听事件</button>
    <button>ie9 attachEvent</button>
    <script>
        var btns=document.querySelectorAll('button');
        // 传统监听事件
        btns[0].onclick=function(){
            alert('haha');
        }
        btns[0].onclick=function(){ // 执行这一个,前面的onclick被这个覆盖
            alert('babab');
        }
        // 方法监听事件     事件侦听注册事件    都可以执行
        btns[1].addEventListener('click',function(){
            alert('2344')
        })
        btns[1].addEventListener('click',function(){
            alert('25679');
        })
        // attachEvent 事件监听方式  只能ie9 以前的浏览器才能使用 了解即可
        btns[2].attachEvent('onclick',function(){
            alert('123');
        })
    </script>
</body>
1.1.4 注册事件兼容性解决方案

兼容性处理原则:先照顾大多数浏览器,再处理特殊浏览器

function addEventListener(element,eventName,fn){
    // 判断当前浏览器是否支持 addEvenListener方法
    if(element.addEventListener){
        element.addEventListener(eventName,fn); // 第三个参数默认是false
    }else if(element.attachEvent){
        element.attachEvent('on'+eventName,fn);
    }else{
        // 相当于 element.οnclick=fn
        element['on'+eventName]=fn;
    }
}
1.2 删除事件(解绑事件)
  1. 传统注册事件:eventTarget.οnclick=null;
  2. 方法监听注册方式:eventTarget.removeEventListener(type,listener[, useCapture])
  3. ie9以前专用:eventTarget.detachEvent(eventNameWithOn,callback)
<body>
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <script>
        var divs=document.querySelectorAll('div');
        divs[0].onclick=function(){
            alert(11);
            // 传统方式解绑
            divs[0].onclick=null;
        }
        // 方法监听注册方式解绑
        divs[1].addEventListener('click',fn)    // 里面的fn不需要调用加小括号
        function fn(){
            alert(22);
            divs[1].removeEventListener('click',fn);
        }
        // 3. ie9以前专用监听方式 解绑
        divs[2].attachEvent('onclick',fn1)
        function fn1(){
            alert(33);
            divs[2].detachEvent('onclick',fn1);
        }
        // 封装兼容性解决方案
        function removeEventListener(element,eventName,fn){
            // 判断当前浏览器是否支持 removeEvenListener方法
            if(element.removeEventListener){
                element.removeEventListener(eventName,fn); // 第三个参数默认是false
            }else if(element.detachEvent){
                element.detachEvent('on'+eventName,fn);
            }else{
                // 相当于 element.οnclick=null
                element['on'+eventName]=null;
            }
        }
    </script>
</body>
1.3 DOM事件流

事件流描述的是从页面中接收事件的顺序

事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流

DOM事件流分为3个阶段

  • 捕获阶段:事件捕获–>网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到最具体的元素接收的过程
  • 当前目标阶段
  • 冒泡阶段: 事件冒泡–>IE最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程

在这里插入图片描述

1.3.1 DOM事件流代码验证

注意:

  1. js代码中只能执行捕获或者冒泡其中的一个阶段
  2. onclick和attachEvent只能得到冒泡阶段
  3. eventTarget.removeEventListener(type,listener[, useCapture]),第三个参数如果是true,表示事件捕获阶段调用事件处理程序,如果是false(默认是false),表示在事件冒泡阶段调用事件处理程序
<style>
       .father {
            overflow: hidden;
            width: 200px;
            height: 200px;
            margin: 200px auto;
            background-color: pink;
            text-align: center;
        }
        
        .son {
            width: 100px;
            height: 100px;
            margin: 50px;
            background-color: purple;
            line-height: 100px;
            color: #fff;
        }
    </style>
<body>
    <div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
        var son=document.querySelector('.son');
        // 捕获阶段,如果 addEventListener第三个参数是true,那么处于捕获阶段
        son.addEventListener('click',function(){
            alert(111);
        },true);
        var father=document.querySelector('.father');
        // 捕获阶段,如果 addEventListener第三个参数是true,那么处于捕获阶段
        father.addEventListener('click',function(){
            alert(222);
        },true);
        // 先弹出222再弹出111

        var son=document.querySelector('.son');
        // 冒泡阶段,如果 addEventListener第三个参数是false,那么处于冒泡阶段
        son.addEventListener('click',function(){
            alert(111);
        },false);
        var father=document.querySelector('.father');
        // 捕获阶段,如果 addEventListener第三个参数是true,那么处于捕获阶段
        father.addEventListener('click',function(){
            alert(222);
        },false);
        // 先弹出111再弹出222
		document.addEventListener('click',function(){
            alert('document');
        })
        // 弹完前面在弹document
    </script>
</body>
1.4 事件对象
1.4.1 什么是事件对象
div.onclick=function(e){
    e=e||window.event
	console.log(e);
}
div.addEventListener('click',function(event){
    console.log(event);
})
  1. event就是一个事件对象,写到侦听函数的小括号里面,当形参来看

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

  3. 事件对象是事件一系列相关数据的集合,跟事件相关的 比如鼠标点击里面就包含了鼠标相关的信息、鼠标坐标

  4. 事件对象可以自己命名,比如event、evt、e

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

1.4.2 事件对象的常见属性和方法
事件对象属性方法说明
e.target返回触发事件对象 标准
e.srcElement返回触发事件对象 非标准
e.type返回事件的类型 比如click、mouseover 不带on
e.cancelBubble该属性阻止冒泡 非标准 ie6-8使用
e.returnValue该属性阻止默认事件(默认行为) 非标准 ie6-8使用,比如不让链接跳转
e.preventDefault()该属性阻止默认事件(默认行为) 标准 ie6-8使用,比如不让链接跳转
e.stopPropagation()阻止冒泡 标准
// e.target与this的区别
<body>
    <div>123</div>
    <ul>
        <li>abc</li>
        <li>abc</li>
        <li>abc</li>
    </ul>
    <script>
        var div=document.querySelector('div');
        div.addEventListener('click',function(e){
            console.log(e.target);  // <div>123</div>  返回触发事件的对象(元素)
            console.log(this);  // <div>123</div>   返回的是绑定事件的对象(元素)
        })
        var ul=document.querySelector('ul');
        ul.addEventListener('click',function(e){
            // 给ul绑定了事件 this指向ul   e.target指向li
            console.log(this);  // <ul>...</ul>
            console.log(e.target);  // <li>abc</li>
        })
        // 兼容处理 了解即可
        div.onclick=function(e){
            e=e||window.event;
            var target=e.target||e.srcElement;
            console.log(target);
        }
// 与this相似的属性 currentTarget ie6-8 不认识
    </script>
</body>
// 阻止默认行为
<body>
    <div>123</div>
    <a href="http://www.baidu.com">百度</a>
    <form action="http://www.baidu.com">
        <input type="submit" value="提交" class="sub">
    </form>
    <script>
        // 返回事件类型 
        var div=document.querySelector('div');
        div.addEventListener('click',fn);
        function fn(e){
            console.log(e.type);    // click
        }
        // 阻止默认事件 让链接不跳转或者提交不提交
        var a=document.querySelector('a');
        a.addEventListener('click',function(e){
            e.preventDefault(); // dom标准写法
        })
        // 传统的注册方式
        a.onclick=function(e){
            // 普通浏览器 e.preventDefault(); 方法
            e.preventDefault();
            // 低版本浏览器 ie6-8   属性
            e.returnValue;
            // return false 也可以阻止默认行为,没有兼容性问题  return后面的代码不执行,只限于传统的注册
            return false;
        }
    </script>
</body>
1.5 阻止事件冒泡

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

  1. 标准写法:利用事件对象里面的stopPropagation()方法
  2. 非标准写法:IE 6-8 利用事件对象cancelBubble属性
<body>
    <div class="father">
        <div class="son">son盒子</div>
    </div>
    <script>
        var son=document.querySelector('.son');
        // 冒泡阶段,如果 addEventListener第三个参数是false,那么处于冒泡阶段
        son.addEventListener('click',function(e){
            alert('son');
            // e.stopPropagation();
            // e.cancelBubble=true;
            // 兼容性解决方法
            if(e&&e.stopPropagation){
                e.stopPropagation();
            }else{
                window.event.cancelBubble=true;
            }
        },false);
        var father=document.querySelector('.father');
        // 捕获阶段,如果 addEventListener第三个参数是true,那么处于捕获阶段
        father.addEventListener('click',function(){
            alert('father');
        },false);
		document.addEventListener('click',function(){
            alert('document');
        })
    </script>
</body>
1.6 事件委托(代理、委派)

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

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

事件委托的作用:只操作了一次DOM,提高了程序的性能

<body>
    <ul>
        <li>知否知否,应是绿肥红瘦</li>
        <li>知否知否,应是绿肥红瘦</li>
        <li>知否知否,应是绿肥红瘦</li>
        <li>知否知否,应是绿肥红瘦</li>
    </ul>
    <script>
        // 事件委托的核心:给父节点添加侦听器,利用事件冒泡影响每一个子节点
        var ul=document.querySelector('ul');
        var flag=true;
        ul.addEventListener('click',function(e){
            // alert('知否知否,应是绿肥红瘦');
            // e.target可以得到点击的对象
            e.target.style.backgroundColor='blue';
        })

        //利用排他法进行操作
        var lis = document.getElementsByTagName('li');
        for (let i = 0; i < lis.length; i++) {
            lis[i].onclick = function() {
                for (let j = 0; j < lis.length; j++) {
                    lis[j].style.backgroundColor ='';
                    // lis[i].style.backgroundColor = 'pink';
                }
                lis[i].style.backgroundColor='pink';
            }
        }
    </script>
</body>
1.7 常用的鼠标事件
1.7.1 鼠标事件
  1. 禁止鼠标右键菜单:contextmenu主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单

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

    <body>
     我是一段不愿意分享的文字
     <script>
         // 1. 禁用右键菜单
         document.addEventListener('contextmenu',function(e){
             e.preventDefault();
         })
         // 2. 禁止鼠标选中
         document.addEventListener('selectstart',function(e){
             e.preventDefault();
         })
     </script>
    
1.7.2 鼠标事件对象

event对象代表事件的状态,跟事件相关的一系列信息的集合,现阶段主要用鼠标事件对象MouseEvent和键盘事件对象KeyboardEvent

鼠标事件对象说明
e.clientX返回鼠标相对于浏览器窗口可视区的X坐标
e.clientY返回鼠标相对于浏览器窗口可视区的Y坐标
e.pageX返回鼠标相对于文档页面的X坐标 IE9+支持
e.pageY返回鼠标相对于文档页面的Y坐标 IE9+支持
e.screenX返回鼠标相对于电脑屏幕的X坐标
e.screenY返回鼠标相对于电脑屏幕的Y坐标
<body>
    <script>
        // 鼠标对象事件 MouseEvent
        document.addEventListener('click',function(e){
            // 浏览器可视区的x和y坐标
            console.log(e.clientX,e.clientY);   // 166 50
            // 文档页面的x和y坐标
            console.log(e.pageX,e.pageY);   // 166 72
            // 电脑屏幕的x和y坐标
            console.log(e.screenX,e.screenY);   // 758 138
        })
    </script>
</body>
1.8 常用键盘事件
1.8.1 三个键盘事件
键盘事件触发条件
onkeyup某个键盘按键被松开时触发
onkeydown某个键盘按键被按下时触发
onkeypress某个键盘按键被按下时触发,但是它不识别功能键,比如 Ctrl shift 箭头等
<body>
    <script>
        // 1. onkeyup
        // document.οnkeyup=function(){
        //     alert('我弹起了');
        // }
        document.addEventListener('keyup',function(){
            console.log('我弹起了');
        })
        // 2. onkeydown
        document.addEventListener('keydown',function(){
            console.log('我按下了down');
        })
        // 3. onkeypress
        document.addEventListener('keypress',function(){
            console.log('我按下了press');
        })
        // 三个事件的执行顺序:keydown-->keypress-->keyup
    </script>
</body>
1.8.2 键盘事件对象
键盘事件对象属性说明
keyCode返回该键的ASCII值,能区分大小写
<body>
    <script>
        // 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值
        document.addEventListener('keyup',function(e){
            console.log(e.keyCode);
            // 1. 我们的keyup与keydown事件不区分字母大小写
            // 2. keypress事件区分字母大小写
            // 3. 可以利用keyCode返回的ASCII码值来判断用户按下了哪个键
            if(e.keyCode===65){
                alert('你按下了a键');
            }else{
                alert('你没有按下a键');
            }
        })
    </script>
</body>

2. BOM 浏览器对象模型

2.1 BOM概述
  1. BOM 即浏览器对象模型,,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window
  2. BOM是由一系列相关的对象构成,并且每个对象都提供了很多方法和属性
  3. BOM缺乏标准,JavaScript语法的标准化组织是ECMA,DOM的标准化组织是W3C,BOM最初是Netscape浏览器标准的一部分
  4. BOM是浏览器厂商在各自浏览器上定义的,兼容性较差
  5. BOM包含DOM
  6. window对象是浏览器的顶级对象,具有双重角色:是js访问浏览器窗口的一个接口;是一个全局对象,定义在全局作用域中的变量,函数都会变成window对象的属性和方法。(window下的一个特殊属性window.name)
2.2 window 常见事件
2.2.1 窗口加载事件
  1. window.load窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS文件等),就调用的处理函数(使用这个之后,js文件可以放在任何位置,但这个只能写一次,如果有多个,就以最后一个为准)

  2. DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表、图片和flash等 ie9以上支持

<body>
    <!-- 窗口加载事件 -->
    <script>
        // window.οnlοad=function(){
        //     var input=document.querySelector('button');
        //     input.addEventListener('click',function(){
        //         alert('点击了');
        //     })
        // }
            window.addEventListener('load',function(){
                var input=document.querySelector('button');
                input.addEventListener('click',function(){
                    alert('点击了');
                })
            })
            document.addEventListener('DOMContentLoaded',function(){
                alert(33);
            })
            //load事件等页面内容全部加载完毕才会执行,DOMContentLoaded是DOM加载完毕,就可以执行
    </script>
    <button>点击</button>
</body>
2.2.2 调整窗口大小事件

window.onresize:是调整窗口大小加载事件,当触发时就调用的处理函数

注意:

  1. 只要窗口大小发生变化,就会触发这个事件
  2. 利用这种事件完成响应式布局,window.innerWidth当前屏幕的宽度
	<style>
        div{
            width: 200px;
            height: 200px;
            background-color: pink;
        }
    </style>
<body>
    <script>
        window.addEventListener('load',function(){
            var div=document.querySelector('div');
            window.addEventListener('resize',function(){
                console.log('变化了');
                if(window.innerWidth<=800){
                    div.style.display='none';
                }else{
                    div.style.display='block';
                    console.log(111);
                }
            })
        })
    </script>
    <div></div>
</body>
2.3 定时器
2.3.1 常见定时器设置
  1. window.setTimeout(调用函数,[延迟的毫秒数]):设置一个定时器,该定时器到期后执行调用函数
  2. window.setInterval(回调函数,[延迟的毫秒数]):重复调用一个函数,每隔这个时间,就去调用一次回调函数
  3. window.clearTimeout(timeoutID):停止定时器
<body>
    <button>点击停止定时器setTimeout</button>
    <button>点击停止定时器setInterval</button>
    <script>
        var btn=document.querySelectorAll('button');
        // 1. setTimeout  window可以省略 延时时间单位是毫秒,可省略,默认是0 调用函数可直接写函数,还可写函数名,也可写 '函数名()'
        setTimeout(function(){
            console.log('时间到了');
        },2000);
        function callback(){
            console.log('爆炸了');
        }
        // 页面中可能有很多的定时器,我们经常给定时器加标识符(名字)
        var time1=setTimeout(callback,5000);
        var time2=setTimeout(callback,2000);
        // 停止定时器
        btn[0].addEventListener('click',function(){
            clearTimeout(time1);
        })
        // 2. setInterval 时间到了,会间隔同样的时间不断调用这个函数
        var time3=setInterval(function(){
            console.log('继续输出');
        },1000);
        // 停止定时器
        btn[1].addEventListener('click',function(){
            clearInterval(time3);
        })
    </script>
</body>
2.3.2 this指向问题
  1. 全局作用域或者普通函数中this指向全局对象window(注意定时器里面的this指向window)
  2. 方法调用中谁调用this指向谁
  3. 构造函数中this 指向构造函数的实例
2.4 JS 执行队列

JS 原来是单线程:JavaScript语言的一大特点是单线程,也就是说,同一时间只能做一件事

2.4.1 同步和异步
  1. 同步:前一个任务结束之后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的
  2. 异步:在做一件事可以处理其他事情,可同时处理多个任务
  3. 同步任务:都在主线程上执行,形成一个执行栈
  4. 异步任务:js的异步是通过回调函数实现的,有以下三种类型:
    • 普通事件:如click、resize等
    • 资源加载:如load、error等
    • 定时器、包括setTimeout、setInterval等
2.4.2 js执行机制
  1. 先执行执行栈中的同步任务
  2. 异步任务(回到函数)放入任务队列中
  3. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行

由于主线程不断地重复获得任务,执行任务、在获取任务、再执行,所以这种机制被称为事件循环(event loop)

2.5 location 对象

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

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

URL的一般语法格式:

protocol://host[:port]/path/[?query]#fragment (protocol:通信协议,常用的http,ftp,maito;host:主机(域名);port:端口号;path:路径;query:参数;fragment:片段 #后面内容,常见于链接 锚点 )

比如:http://www.itcast.cn/index.html?name=andy&age=18#link

2.5.1 location 属性
location对象属性返回值
location.href获取或者设置整个URL
location.host返回主机(域名) www.itheima.com
location.port返回端口号 如果未写返回空字符串
location.pathname返回路径
location.search返回参数
location.hash返回片段 #后面的内容,常见于链接、锚点
2.5.2 location 方法
location对象方法返回值
location.assign()跟href一样,可以跳转页面(也称为重定位页面)
location.replace()替换当前页面,因为不记录历史,所以不能后退页面
location.reload()重新加载页面,相当于刷新按钮,或者F5,如果参数为true,则强制刷新ctrl+F5
<body>
    <!-- 常见方法 -->
    <button>点击</button>
    <script>
        var btn=document.querySelector('button');
        btn.addEventListener('click',function(){
            // assign可后退
            // location.assign('http://www.baidu.com');
            // replace不记录浏览历史,不支持后退功能
            // location.replace('http://www.baidu.com');
            location.reload(true);
        })
    </script>
</body>
2.6 navigator 对象

navigator对象包含有关浏览器的信息,它有很多属性,最常用的是userAgent,该属性可以返回由客户机发送服务器的user-agent头部的信息。

// 判断用户哪个终端打开页面,实现跳转
<script>
  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 = ""; //手机
        }
    </script>
2.7 history 对象

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

history对象方法作用
back()可以后退功能
forward()前进功能
go(参数)前进后退功能 参数如果是1,前进一个页面,如果是-1,后退一个页面
<body>
    <a href="../js深入学习2/12-获取URL参数/index.html">点击我去往下一个页面</a>
    <button>前进</button>
    <script>
        var btn=document.querySelector('button');
        btn.addEventListener('click',function(){
            // history.forward();
            history.go(1);
        })
    </script>
</body>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值