资讯专栏INFORMATION COLUMN

js高级程序设计-事件处理-阅读笔记

Anshiii / 2094人阅读

摘要:事件流事件流是指从页面接受事件的顺序一般考虑兼容性问题会使用冒泡而不适用捕获事件冒泡事件开始时由具体的元素嵌套层次最深的元素接受然后逐级向上传播到文档事件捕获基本跟事件冒泡相反事件捕获用于在于事件到达预定目标之前捕获他首先接收到事件然后事件

事件流

事件流是指从页面接受事件的顺序

一般考虑兼容性问题,会使用冒泡而不适用捕获

事件冒泡event bubbling

事件开始时由具体的元素(嵌套层次最深的元素)接受,然后逐级向上传播到文档document

事件捕获

基本跟事件冒泡相反,事件捕获用于在于事件到达预定目标之前捕获他,document首先接收到事件,然后事件依次向里传递,一直到传播事件的实际目标,例如这个div是我们点击的那个div


事件捕获用的不多

dom事件流

DOM2级事件,规定的事件流包括三个阶段

事件捕获阶段

处于目标阶段

事件冒泡阶段

其实每一个事件都是有这么一个阶段转换过程的

事件处理程序 html事件处理 (不建议使用)

即在html中写的事件
两种使用方式

   

缺点:不方便mvc分离,代码混乱

DOM0级事件处理程序

将一个函数赋值给一个事件处理程序属性

主动式的事件处理

    var btn = document.getElementById("myBtn");
    //主动赋值给onclick属性
    btn.onclick = function () {
        console.log("Clicked");
    }
    btn.onclick = null; // 删除事件处理程序
DOM2级事件处理程序

addEventListener() 添加事件处理程序监听

removeEventListener() 移除事件处理程序监听

所有DOM节点中都包含这两个方法

被动式的事件处理

可以添加多个多个事件处理程序,他们会按照添加的顺序触发

大多数情况下,都是将时间处理程序添加到事件流的冒泡阶段,这样可以最大限度的兼容各种浏览器.

最好只在需要在事件到达目标之前截获他的时候将时间处理程序添加到捕获阶段

        var btn = document.getElementById("myBtn");
        //三个参数,要处理的事件名,作为事件处理程序的函数和一个布尔值
        btn.addEventListener("click",function () {
            alert(this.id);
            //true表示捕获阶段调用事件处理程序,false表示在冒泡阶段调用事件处理程序
        },false)

removeEventListener只能移除添加时传入的函数,所以匿名函数是没办法移除的(匿名函数没有办法确定是同一个)

    var btn = document.getElementById("myBtn");
    //将匿名函数改成有名函数
    var handler = function () {
        alert(this.id);
    };
    btn.addEventListener("click",handler,false);
    //可以移除
    btn.removeEventListener("click",handler,false);
事件对象

在触发DOM上的某个事件时,会产生一个事件对象event,这个对象包含着所有与事件相关的信息. 事件属性查看

    var btn = document.getElementById("myBtn");
    //这个event就是事件对象,里面的属性可以直接调用查看
    btn.onclick = function (event) {
        alert(event.type);//返回click
    };
    btn.addEventListener("click",function (event) {
        alert(event.type);//返回click
    },false)

如果点击一个在body里面的myBtn元素:

    document.body.onclick = function (event) {
        console.log(event.currentTarget === document.body); //返回true
        console.log(this === document.body); //返回true
        console.log(event.target === document.getElementById("myBtn")); //返回true
    }

1.currentTarget代表事件处理程序当前正在处理的事件的那个元素,那么本例子的话就是body,另外this也是body,因为事件处理程序是注册到body 上的
2.target是事件的目标,即点击的那个元素,就是myBtn
3.需要注意的是即使点击了一个元素,但是因为最终都会冒泡到body那里,所以事件处理处理会在冒泡到最外层进行处理

通过判断事件对象的type来触发不同的事件处理程序,用于需要通过一个函数处理多个事件时.

    var btn = document.getElementById("myBtn");
    var handler = function (event) {
        switch (event.type) {
            case "click":
                alert("Clicked");
                break;
            case "mouseover":
                event.target.style.backgroundColor = "red";
                break;
            case "mouseout":
                event.target.style.backgroundColor = "";
                break;
        }
    };
    btn.onclick = handler;
    btn.onmouseover = handler;
    btn.onmouseout = handler;
阻止特定事件的默认行为preventDefault()

默认行为可以使点击a标签的时候跳转到另外一个页面,或者内容超出一定大小的滚动事件

//假设myLink是一个a标签
    var link = document.getElementById("myLink");
    link.onclick = function (event) {
        //阻止了url 默认行为跳转
        event.preventDefault();
    };

需要注意的是只有cancelable属性设置为true的事件,才可以使用preventDefault(),这个属性可以在浏览器调试模式里面看,也可以打印出来

停止事件在DOM层次中传播,例如事件冒泡
    var btn = document.getElementById("myBtn");
    btn.onclick = function (event) {
        alert("mgBtn click");
        //如果没有屏蔽传播的话,会出现两次alert,因为事件会传播到body,也会被触发然后执行
        event.stopPropagation();
    };
    document.body.onclick = function (event) {
        alert("body click");
    }
事件对象的eventPhase属性

用来确定事件当前正位于事件流的哪个阶段

捕获阶段调用的事件处理程序 值为1

事件处理程序处于目标对象上 值为2

在冒泡阶段调用的事件处理程序 值为3

    var btn = document.getElementById("myBtn");
    btn.onclick = function (event) {
        alert("btn:" + event.eventPhase); //返回2
    };
    document.body.addEventListener("click", function (event) {
        alert("body-1:" + event.eventPhase);//返回1
    }, true); // 这里是true代表在捕获阶段

    document.body.onclick = function (event) {
        alert("body-2:" + event.eventPhase);//返回3
    }

首先是返回1,因为是在捕获阶段触发,按照流程上是先捕获然后再到目标再到冒泡的,而捕获阶段是从最外层往里传播的,所以是body

然后是到达了目标myBtn,所以返回2
3.再到返回3,冒泡阶段,是从最里往外传播,最里的是myBtn,最外是body,所以触发了最后的body事件处理程序

ie事件(暂时不看) 事件类型 ui事件

load
当页面完全加载后在window上面触发(包括所有img,js,css等)

    window.addEventListener("load",function (event) {
        alert("loaded");
    })

在DOM2级事件规范,应该在document而非window上面触发load事件,但是所有浏览器都在window上面实现了该事件,所以这样用确保兼容性

也可以多带带对某个元素的加载进行触发

    var img = document.getElementById("myImg");
    img.addEventListener("load",function (event) {
        //这个加载是指图片完全加载完成,包括下载成功
        alert(event.src);
    });
    window.addEventListener("load", function (event) {
        //创建了img元素
        var img = document.createElement("img");
        //添加load事件监听
        img.addEventListener("load", function (event) {
            alert("aa");
        });
        //输出到dom树
        document.body.appendChild(img);
        //设置src后,img才会开始加载
        img.src = "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png";
    })

img只有设置了src属性才会开始下载
script文件的话,只有设置了src并且放到dom树里面才会开始下载

确定js文件是否加载成功

    window.addEventListener("load", function (event) {
        //创建了script元素
        var script = document.createElement("script");
        //添加load事件监听
        script.addEventListener("load", function (event) {
            alert("Loaded");
        });
        //script设置src后,并且添加到dom树后才会开始加载
        script.src = "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.js";
        //输出到dom树
        document.body.appendChild(script);
    })

unload
与load事件对应,这个事件在文档被完全卸载后触发,例如用户从一个页面切换到另外一个页面,一般用于清楚引用,避免内存泄露

    window.addEventListener("unload", function (event) {
        alert("aaa");
    })

abort
在用户停止下载过程时,如果嵌入的内容没有加载完,则在对象元素上触发

error

当发生js错误时在window上面触发

当无法加载图像时,在img触发

如果嵌入的内容没有加载完,则在对象元素上触发

select
当用户选择文本框 input或texterea中的一个或多个字符时触发

resize
调整浏览器窗口的高度或者宽度的时候触发

scroll
当用户滚动带滚动条的元素中的内容时,在该元素上触发

焦点事件

blur 在元素失去焦点时触发

DOMFocusIn 用下面的

DOMFocusOut 用下面的

focus 在元素获得焦点时触发,这个事件不会冒泡

focusin 在元素获得焦点时触发,会冒泡

focusout 在元素失去焦点时触发

即使focus和blur不冒泡,但是也可以在捕获阶段侦听到

鼠标事件

click 单击

dblclick 双击

mousedown 用户按下了鼠标按钮

mouseenter 鼠标从元素外部首次移动到元素范围之内

mouseleave 鼠标从元素范围内移动到元素范围外

mousemove 鼠标在元素内部移动时重复触发

mouseout 鼠标在元素上方

mouseover 当鼠标指针位于一个元素外部,然后用户将其首次移入另外一个元素边界之内触发

mouseup 用户释放鼠标按钮时触发

除了mouseenter 和mouseleave,所有鼠标事件都会冒泡

触摸设备

轻击可单击元素会触发mousemove事件,如果此操作会导致内容变化,将不再有其他事件发生,如果屏幕没有因此变化,那么会依次发生mousedown,mouseup和click事件

轻击不可单击元素不会触发任何事件

两个手指放在屏幕上且页面随手指移动而滚动时会触发mousewheel和scroll事件

滚轮事件

mousewheel,值是event.wheelDelta,方向是用正负判断

文本事件和键盘事件

keydown 当用户按下减胖上的任意键时触发,而且如果按住不放的话会重复触发

keypress 当用户按下键盘的字符键时触发,而且如果按住不放的话会重复触发

keyup 当用户释放键盘上的按键时触发
首先会触发keydown,然后keypress,然后keyup

需要知道键码,对应不同的按键

字符编码(ASCII编码),用户按键后输入的屏幕文本的显示内容,用charCode属性,用String.fromCharCode()转换为实际的字符

只有一个文本事件,textInput,用户按下能够输入实际字符的键时才会触发

textInput的事件的对象里面有一个属性inputMethod,用来分辨文本输入到文本框的方式

0   不确定是怎么输入
1   键盘输入
2   文本粘贴
3   拖放进来的
4   IME输入
5   通过表单中选择某一项输入
6   手写输入
7   语音输入
8   通过几种方式组合输入
9   通过脚本输入
变动事件

dom变动的时候触发

删除节点
replaceChild的时候

插入节点
appendChild(),replaceChild()或insertBefor()的时候

html5事件

DOMContentLoaded事件,相对于load事件会在页面中的一切都加载完成后触发,这个的话,就只会在dom树加载完成后触发,不理会其他img,js文件,css文件之类的
jquery的document.ready()的加载方式就是使用跟这个

pageshow和pagehide事件
在页面显示触发(在load之后)和在页面隐藏时触发(在unload之前)

hashchange事件
url参数列表的锚点!!!变化的时候通知开发人员,锚点是#这样的

    window.addEventListener("hashchange", function (event) {
        console.log(event); //返回一个对象
//        console.log("old url:" + event.oldURL + "new url:" + event.newURL);
    },false);

返回的对象里面有很多有用的信息,例如

newURL
:
"http://localhost:63342/test-webstorm/test5.html?_ijt=dhn30q02o026mo2upn01tav7jn#dsad"
oldURL
:
"http://localhost:63342/test-webstorm/test5.html?_ijt=dhn30q02o026mo2upn01tav7jn"
设备事件

跳过

触摸手势事件

touchstart 当手指触摸屏幕时触发

touchmove 当手指滑动时连续触发

touchend 当手指离开屏幕时触发

touchcancel 当系统停止跟中触摸时触发
每个触摸事件都有一些属性

clientX,clientY(视口),screenX,screenY(屏幕),pageX,pageY(页面) 一些坐标属性

target 触摸的dom节点目标

touches 表示当前跟踪的触摸操作的touch对象数组,每次触摸都会生成一个对象数组,这个对象数组只有一个对象,所以用[0]调用

targetTouches 特定于事件目标的touch对象的数组

changeTouches 一个 TouchList 对象,包含了代表所有从上一次触摸事件到此次事件过程中,状态发生了改变的触点的 Touch 对象,每次触摸都会生成一个对象数组,这个对象数组只有一个对象,所以用[0]调用

    function handleTouchEvent(event) {
        //只跟踪一次触摸
        if (event.touches.length == 1) {
            switch (event.type) {
                case "touchstart":
                    console.log("touch stared(" + event.touches[0].clientX + "," + event.touches[0].clientY + ")");
                    break;
                case "touchend":
                    console.log("touch end(" + event.changedTouches[0].clientX + "," + event.changedTouches[0].clientY + ")");
                    break;
                case "touchmove":
                    //阻止默认滚动行为
                    event.preventDefault();
                    console.log("touch moved(" + event.changedTouches[0].clientX + "," + event.changedTouches[0].clientY + ")");
                    break;
            }
        }
    }
    window.addEventListener("touchstart", handleTouchEvent);
    window.addEventListener("touchend", handleTouchEvent);
    window.addEventListener("touchmove", handleTouchEvent);
内存与性能 事件委托

解决事件处理程序过多的问题

通过添加一次事件可以绑定所有的li,利用冒泡的特性

    var list = document.getElementById("myLinks");
    list.addEventListener("click",function (event) {
        //event事件对象有target属性,里面还有id
        //根据里面的不同的id来触发不同的事件处理逻辑
        //每一个li都能够冒泡到上层的ul,所以可以得到被处理
        switch (event.target.id){
            case "test1":
                console.log("test111111");
                break;
            case "test2":
                console.log("test22222");
                break;
        }
    });
移除事件处理程序

空事件处理程序过多也会导致性能不好
例如手动设置null

btn.onclick = null;

但是没说有对于addEventListener那种处理.

模拟事件

模拟事件在测试web应用程序时候是一种极其有用的技术

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81235.html

相关文章

  • js高级程序设计-DOM-阅读笔记

    摘要:节点层次类型和属性假设我的是一个元素返回至于就是元素的名称节点关系每个节点都有一个属性其中保存着一个对象是一个类数组对象这个对象有属性但不属于对象会随着结构变化而变化因为是类数组所以访问里面的属性可以使用索引也可以使用方法效果是一样的 节点层次 showImg(https://segmentfault.com/img/bVIl1b?w=646&h=407); node类型-dom1 ...

    mating 评论0 收藏0
  • JS高级程序设计笔记——事件(一)

    摘要:但是通过添加的匿名函数无法移除,最好是在其他地方定义事件处理程序的函数,然后将该函数的名称传给第二个参数。一中的事件对象对象兼容级和级的浏览器将对象传入到事件处理程序中。 一、事件流 假设有如下HTML代码: Event Click me 其DOM树如下图所示:showImg(https://segmentfault.com/img/bVUUWA?w=50...

    guqiu 评论0 收藏0
  • 读书笔记(04) - 错误监控 - JavaScript高级程序设计

    摘要:项目中我们可通过设置采集率,或对规定时间内数据汇总再上报,减少请求数量,从而缓解服务端压力。借鉴别人的一个例子只采集上报错误参考文档高级程序设计如何优雅处理前端异常作者以乐之名本文原创,有不当的地方欢迎指出。 showImg(https://segmentfault.com/img/bVbnuud?w=640&h=640); 错误类型 即时运行错误 (代码错误) 资源加载错误 常见...

    Null 评论0 收藏0
  • 正则表达式

    摘要:最全正则表达式总结验证号手机号中文邮编身份证地址等是正则表达式的缩写,作用是对字符串执行模式匹配。学习目标了解正则表达式语法在中使用正则表达式在中使 JS高级技巧 本篇是看的《JS高级程序设计》第23章《高级技巧》做的读书分享。本篇按照书里的思路根据自己的理解和经验,进行扩展延伸,同时指出书里的一些问题。将会讨论安全的类型检测、惰性载入函数、冻结对象、定时器等话题。1. 安全的类型检测...

    yibinnn 评论0 收藏0
  • 《JavaScript高级程序设计笔记:基本概念

    摘要:一写在前面最近重读高级程序设计,总结下来,查漏补缺。但这种影响是单向的修改命名参数不会改变中对应的值。这是因为对象的长度是由传入的参数个数决定的,不是由定义函数时的命名参数的个数决定的。实际改变会同步,改变也会同步 一、写在前面 最近重读《JavaScript高级程序设计》,总结下来,查漏补缺。 二、JS简介 2.1 JS组成 ECMAscript:以ECMA-262为基础的语言,由...

    ygyooo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<