(一)JS 事件分类
1. 鼠标事件:
click/dbclick/mouseover/mouseout
2.html 事件:
onload/onunload/onsubmit/onresize/onchange/onfoucs/onscroll
3. 键盘事件:
keydown: 键盘按下时触发
keypress: 键盘按下并抬起的瞬间触发.
keyup: 键盘抬起触发
[注意事项]
1执行顺序: keydown keypress keyup
2keypress 只能捕获数字, 字母, 符号键, 而不能捕获功能键.
3长按时循环执行 keydown--keypress
4有 keydown, 并不一定有 keyup, 当长按时焦点失去, 将不再触发 keyup
5keypress 区分大小写, keydown,kewup 不区分.
4. 事件因子:
当触发一个事件时, 该事件将向事件所调用的函数中, 默认传入一个参数,
这个参数就是一个事件因子, 包含了该事件的各种详细信息.
- document.onkeydown=function(e){
- console.log(e);
- }
- document.onkeydown=function(){
- console.log(Windows.event);
- }
- // 兼容浏览器的写法:
- document.onkeydown=function(e){
- e==e||Windows.event;
- var Code=e.keyCode||e.which||e.charCode;
- if(code==13){
- // 回车
- }
- }
5. 如何确定键盘按键?
1再出发的函数中, 接收事件因子 e.
2可以使用 e.key 直接去到按下的按键字符 (不推荐使用).
3一次可以使用 keyCode/which/charCode 取到按键的 ASCII 码值.
- (兼容各种浏览器的写法)
- var Code=e.keyCode||e.which||e.charCode;
- // 判断组合键
- var isAlt=0,isEnt=0;
- document.onkeyup=function(e){
- if(e.keyCode==18){
- // 前端全栈开发交流圈: 866109386
- isAlt=1; // 面相 1-3 年前端开发人员
- } // 帮助突破技术瓶颈, 提升思维能力, 欢迎大家进来.
- if(e.keyCode==13){
- isEnt=1;
- }
- if(isAlt==1&&isEnt==1){
- alert("同时按下 Alt 和 Enter 键");
- }
- }
- document.onkeyup=function(){
- console.log("keyup");
- }
- document.onkeypress=function(){
- console.log("keypress");
- }
- document.onkeydown=function(){
- console.log("keydown");
- }
- document.onkeypress=function(){
- console.log(Windows.event);
- }
- // 判断是否按下了回车键
- document.onkeydown=function(e){
- var code=e.keyCode;
- if(code==13){
- alert("你输入的是回车键");
- }
- }
二, 事件绑定模型
(一)DOM0 事件模型
绑定注意事项:
1使用 Windows.onload 加载完成后进行绑定.
Windows.onload =function(){// 事件}
2放在 body 后面进行绑定.
- //body 内容
- <body>
- <button onclick="func()"> 内联模型绑定 </button>
- <button id="btn1"> 哈哈哈哈 </button>
- <button id="btn2">DOM2 模型绑定 </button>
- <button id="btn3"> 取消 DOM2</button>
- </body>
1. 内联模型 (行内绑定): 将函数名直接作为 HTML 标签中属性的属性值.
<button onclick="func()"> 内联模型绑定 </button>
缺点: 不符合 w3c 中关于内容与 行为分离的基本规范.
2. 脚本模型 (动态绑定): 通过在 JS 中选中某个节点, 然后给节点添加 onclick 属性.
document.getElementById("btn1")=function(){}
优点: 符合 w3c 中关于内容与行为分离的基本规范, 实现 HTML 与 JS 的分离.
缺点: 同一个节点只能添加一次同类型事件, 如果添加多次, 最后一个生效.
- document.getElementById("btn1").onclick=function(){
- alert(1234);
- }
- document.getElementById("btn1").onclick=function(){
- alert(234);
- }// 重复的只能出现最近的一次
3.DOM0 共有缺点: 通过 DOM0 绑定的事件, 一旦绑定将无法取消.
- document.getElementById("btn3").onclick=function(){// 不能取消匿名函数
- if(btn.detachEvent){
- btn.detachEvent("onclick",func1);
- }else{
- btn.removeEventListener("click",func1);
- }
- alert("取消 DOM2");
- }
(二)DOM2 事件模型
1. 添加 DOM2 事件绑定:
1IE8 之前, 使用. attachEvent("onclick", 函数);
2IE8 之后, 使用. addEventListener("click", 函数, true/false);
参数三: false(默认) 表示事件冒泡, 传入 true 表示事件捕获.
3兼容所有浏览器的处理方式:
- var btn=document.getElementById("btn1");
- if(btn.attachEvent){
- btn.attachEvent("onclick",func1);// 事件, 事件需要执行的函数 IE8 可以
- }else{
- btn.attachEventListener("click",func1);
- }
2.DOM2 绑定的优点:
1同一个节点, 可以使用 DOM2 绑定多个同类型事件.
2使用 DOM2 绑定的事件, 可以有专门的函数进行取消.
3. 取消事件绑定:
1使用 attachEvent 绑定, 要用 detachevent 取消.
2使用 attachEventListener 绑定, 要用 removeEventListenter 取消.
注意: 如果 DOM2 绑定的事件, 需要取消, 则绑定事件时, 回调函数必须是函数名,
而不能是匿名函数, 因为取消事件时, 取消传入函数名进行取消.
三, JS 事件流模型
(一)JS 中的事件流模型
事件冒泡 (fasle / 不写): 当触发一个节点的事件是, 会从当前节点开始, 依次触发其祖先节点的同类型事件, 直到 DOM 根节点.
事件捕获 (true): 当初发一个节点的事件时, 会从 DOM 根节点开始, 依次触发其祖先节点的同类型事件, 直到当前节点自身.
什么时候事件冒泡? 什么时候事件捕获?
1 当使用 addEventListener 绑定事件, 第三个参数传为 true 时表示事件捕获;
2 除此之外的所有事件绑定均为事件冒泡.
阻止事件冒泡:
1 IE10 之前, e.cancelBubble = true;
2 IE10 之后, e.stopPropagation();
阻止默认事件:
1 IE10 之前: e.returnValue = false;
2 IE10 之后: e.preventDefault();
- CSS//
- #div1{
- width: 300px;;
- height: 300px;
- background-color: powderblue;
- }
- #div2{
- width: 200px;
- height: 200px;
- background-color: deeppink;
- }
- #div3{
- width: 100px;
- height: 100px;
- background-color:#A9A9A9;
- }
- //HTML
- <div id="div1">
- <div id="div2">
- <div id="div3"></div>
- </div>
- </div>
- <a href="01 - 事件笔记. html" onclick="func()"> 超链接 </a>
- div1.addEventListener("click",function(){
- console.log("div1 click");
- },false);
- div2.addEventListener("click",function(){
- console.log("div2 click");
- },false);
- div3.addEventListener("click",function(){ // 原来的顺序是: 3-->2-->1.
- // myParagraphEventHandler(); // 截获事件流后, 只触发 3. 但是从 2 开始依然会冒泡;
- console.log("div3 click");
- },false);
结果 (事件冒泡)(由小到大 div3-》div2-》div1):
- div1.addEventListener("click",function(){
- console.log("div1 click");
- },true);
- div2.addEventListener("click",function(){
- console.log("div2 click");
- },true);
- div3.addEventListener("click",function(){
- // myParagraphEventHandler(); // 截获事件流后, 只触发 3. 但是从 2 开始依然会冒泡;
- console.log("div3 click");
- },true);
结果 (事件捕获)(由小到大 div3-》div2-》div1):
- // 依然遵循事件冒泡
- document.onclick=function(){
- console.log("document click")
- }
- // 截获事件流阻止事件冒泡
- function myParagraphEventHandler(e) {
- e = e || Windows.event;
- if (e.stopPropagation) {
- e.stopPropagation(); //IE10 以后
- } else {
- e.cancelBubble = true; //IE10 之前
- }
- }
- // 截获事件流阻止事件冒泡
- function myParagraphEventHandler(e) {
- e = e || Windows.event;
- if (e.stopPropagation) {
- e.stopPropagation(); //IE10 以后
- } else {
- e.cancelBubble = true; //IE10 之前
- }
- }
- // 阻止默认事件
- function eventHandler(e) {
- e = e || Windows.event;
- // 防止默认行为
- if (e.preventDefault) {
- e.preventDefault(); //IE10 之后
- } else {
- e.returnValue = false; //IE10 之前
- }
- }
来源: http://www.qdfuns.com/article/51070/1d6e6d812eb7b4b21e702ceb84d761d1.html