JavaScript每天必学之事件


Posted in Javascript onSeptember 18, 2016

其实这篇文章挺早之前就写了,但是由于sf保存方面的bug,所以当时写了一大堆,结果没保存,觉得这个没写完是个不小的遗憾,今天正好有空,就给补充下了,也正好给我的javascript学习总结做一个完结篇。 

这里,主要讨论一下js相关的事件—— 

事件处理程序 

在DOM中定义了一些事件, 而响应某个事件的函数就叫事件处理程序(或事件侦听器)。事件处理程序的名字一般以“on”开头,例如:onclick等 

事件冒泡与捕获 

事件流指的是页面中接收事件的顺序,IE,火狐和chrome浏览器都是事件冒泡,所谓是事件冒泡指的是事件最开始由最具体的元素接收,然后逐级向上传播到不具体的节点。而事件捕获则正好相反,事件捕获是由Netscape提出的,事件冒泡和捕获具体如下图所示:

JavaScript每天必学之事件 

虽然事件捕获是Netscape唯一支持的事件流模型,但目前IE9,火狐和谷歌也都支持这种事件流模型。 

事件冒泡的好处 

因为事件具有冒泡机制,因此我们可以利用冒泡的原理,把事件加到父级上,触发执行效果。这样做的好处当然就是提高性能了,

<head lang="en">
 <meta charset="UTF-8">
 <title></title>
 <script type="text/javascript">
 window.onload = function () {
  var aUl = document.getElementsById("bubble");
  var aLi = aUl.getElementsByTagName("li");

  for(var i = 0;i<aLi.length;i++){
  aLi[i].onmouseover = function () {
   this.style.backgroundColor = "blue";
  };
  ali[i].onmouseout = function () {
   this.style.backgroundColor = "";
  }
  }
 };
 </script>
</head>
<body>
<div>
 <ul id = "bubble">
 <li>1</li>
 <li>2</li>
 <li>3</li>
 <li>4</li>
 </ul>
</div>
</body>

这样我们就可以做到li上面添加鼠标事件。但是如果说我们可能有很多个li用for循环的话就比较影响性能。 

下面我们可以用事件委托的方式来实现这样的效果。html不变:

<script type="text/javascript">
 window.onload = function () {
 var aUl = document.getElementsById("bubble");
 var aLi = aUl.getElementsByTagName("li");

 //不管在哪个事件中,只要你操作的那个元素就是事件源。
 // ie:window.event.srcElement
 // 标准下:event.target
 aUl.onmouseover = function (ev) {
  var ev = ev || window.event;
  var target = ev.target || ev.srcElement;

  if(target.nodeName.toLowerCase() == "li"){
  target.style.background = "blue";
  }
 };
 aUl.onmouseout = function (ev) {
  var ev = ev || window.event;
  var target = ev.target || ev.srcElement;

  if(target.nodeName.toLowerCase() = "li"){
  target.style.background = "";
  }
 }
 };
</script>

那么,如何阻止事件的冒泡呢,看下面一个例子:

<div onclick="showMsg(this,event)" id="outSide" style="width:100px; height:100px; background:#000; padding:50px">
<div onclick="showMsg(this,event)" id="inSide" style="width:100px; height:100px; background:#CCC"></div>
</div>
<script type="text/javascript">
//阻止事件冒泡后,你点击灰色盒子,整个过程只弹一次对话框了(注意与默认情况对比)
function showMsg(obj,e)
{
 alert(obj.id);
 stopBubble(e)
}

//阻止事件冒泡函数
function stopBubble(e)
{
 if (e && e.stopPropagation)
 e.stopPropagation()
 else
 window.event.cancelBubble=true
}
</script>

点击黑色外围的效果图:

 JavaScript每天必学之事件

DOM 0级事件处理程序 

通过js指定事件处理程序通常是将回调函数赋给这个事件处理程序的属性。每个元素都有自己的事件处理程序属性(属性小写,例如:onclick)

btn.onclick = function(){
 console.log('hello');
};

使用DOM 0级指定的事件处理程序被认为是元素的方法。因此,this指向当前元素:

var btn = document.getElementById('myDiv');

//DOM上触发的事件会产生一个事件对象event
btn.onclick = function (event) {
 alert(this.id);//myDiv 
};

DOM level 1

DOM level 1 专注于 HTML 和 XML 文档模型。它含有文档导航和处理功能。 

DOM level 1 于 1998 年 10 月 1 日成为 W3C 推荐标准。 

第二版的工作草案在 2000 年 9 月 29 日。 

值得一提的是:DOM level 0 并不是 W3C 规范。而仅仅是对在 Netscape Navigator 3.0 和 IE 3.0 中的等价功能性的一种定义。 

DOM 2级事件处理程序 

DOM 2级定义了两个方法,用于指定和删除事件处理程序的操作:addEventListener()和removeEventListener(),他们都接受三个参数:

1.事件名。比如上面的click
2.作为事件处理程序的函数。
3.布尔值(true表示捕获阶段调用事件处理程序,false表示冒泡阶段)

通过Element对象的addEventListener方法,也可以定义事件的回调函数。

//element.addEventListener(event, function, useCapture)

var btn = document.getElementById('myDiv');
btn.addEventListener('click', function () {
 console.log(this.id);
},false);

IE中的事件处理程序 

IE9之前的IE浏览器不支持addEventListener()和removeEventListener()。 

与其他浏览器不同的是,IE使用的是attachEvent()和detachEvent()方法来为DOM添加事件处理程序,由于IE8及更早版本只支持事件冒泡,所以他们只接受两个参数:
1、事件处理程序名称(前面要加on)
2、事件处理程序函数
使用attachEvent()添加的事件处理程序如下:

var btn = document.getElementById('myDiv');
btn.attachEvent('onclick', function () {
 console.log(this.id);
});

值得注意的是,使用attachEvent()方法的情况下,事件处理程序会在全局作用域中运行,所以,此时this等于window 

事件对象
 
在触发DOM上的某个事件时,会产生一个事件对象event,这个对象包含着所有与事件相关的信息。包括导致事件的元素、事件的类型以及其他与特定事件相关的信息。event对象会被作为第一个参数传递给事件监听的回调函数。我们可以通过这个event对象来获取到大量当前事件相关的信息:
 type (String) — 事件的名称
target (node) — 事件起源的DOM节点
currentTarget?(node) — 当前回调函数被触发的DOM节点(后面会做比较详细的介绍)
bubbles (boolean) — 指明这个事件是否是一个冒泡事件(接下来会做解释)
preventDefault(function) — 这个方法将阻止浏览器中用户代理对当前事件的相关默认行为被触发。比如阻止<a>元素的click事件加载一个新的页面
cancelable (boolean) — 这个变量指明这个事件的默认行为是否可以通过调用event.preventDefault来阻止。
stopPropagation (function) — 取消事件的进一步捕获或冒泡,bubbles为true使用这个方法
eventPhase:返回一个数字,表示事件目前所处的阶段,0为事件开始从DOM表层向目标元素传播,1为捕获阶段,2为事件到达目标元素,3为冒泡阶段。

此外,事件对象还可能拥有很多其他的属性,但是他们都是针对特定的event的。比如,鼠标事件包含clientX和clientY属性来表明鼠标在当前视窗的位置。 

另外,stopPropagation()方法用于立即停止事件在DOM中的传播,即取消进一步的事件冒泡或捕获。

var btn = document.getElementById('myDiv');
btn.onclick = function (event) {
 alert("clicked");
 event.stopPropagation();
};

//避免触发在document.body上的事件处理程序
document.body.onclick = function (event) {
 alert("Body clicked"); 
};

只有在事件处理程序执行期间,event对象才会存在,一旦事件处理程序执行完毕,event对象就会自动销毁。 

IE中的事件对象 

在DOM 0级中添加事件处理程序时,event对象是作为window对象的一个属性存在的:

var btn = document.getElementById('myDiv');
btn.onclick = function (event) {
 var event = window.event;
 alert(event.type);//click
};

IE 的event对象同样也包含与创建它的事件相关的属性和方法。
cancleBubble 布尔   默认值时false,但可以被设置成true来取消事件冒泡,与dom中的 stopPropagation()方法相同。
returnValue   布尔    默认值是true,当设置成false时用以取消事件的默认行为 与dom中的preventDefault()相同。
srcElement  元素    事件的目标,与dom中的target属性相同。
type

字符串   被触发的事件类型。

click事件 

当用户点击以后,event对象会包含以下属性。
 pageX,pageY:点击位置相对于html元素的坐标,单位为像素。
clientX,clientY:点击位置相对于视口(viewport)的坐标,单位为像素。
screenX,screenY:点击位置相对于设备显示屏幕的坐标,单位为设备硬件的像素

clientX,clientY 

图示:clientX和clientY,他们的值表示事件发生时鼠标指针在视口中的水平和垂直坐标(不包含滚动条区域)

JavaScript每天必学之事件

偏移量

通过以下4个属性可以取得元素的偏移量。

   (1)offsetHeight:元素在垂直方向上占用的空间大小,以像素计。包括元素的高度、(可见的)水平滚动条的高度、上边框高度和下边框高度。

   (2)offsetWidth:元素在水平方向上占用的空间大小,以像素计。包括元素的宽度、(可见的)垂直滚动条的宽度、左边框宽度和右边框宽度。

   (3)offsetLeft:元素的左外边框至包含元素的左内边框之间的像素距离。

   (4)offsetTop:元素的上外边框至包含元素的上内边框之间的像素距离。

pageX,pageY 

这两个属性表示鼠标光标在页面中的位置,在页面没有滚动的情况下,pageX,pageY的值与clientX,clientY的值相等 

滚动大小 

滚动大小,指的是包含滚动内容的元素的大小。

    以下是4个与滚动大小相关的属性。

   (1)scrollHeight:在没有滚动条的情况下,元素内容的总高度。

   (2)scrollWidth:在没有滚动条的情况下,元素内容的总宽度。

   (3)scrollLeft:被隐藏在内容区域左侧的像素数。通过设置这个属性可以改变元素的滚动位置。

   (4)scrollTop:被隐藏在内容区域上方的像素数。通过设置这个属性可以改变元素的滚动位置。

焦点事件 

焦点事件会在页面元素获得或失去焦点时触发,有以下4个焦点事件:
 1.blur:元素失去焦点时触发,该事件不冒泡
 2.focus:元素获得焦点时触发。不冒泡
 3.focusin:元素获得焦点时触发,冒泡
 4.focusout:元素失去焦点时触发,冒泡 

鼠标事件 

DOM 3级定义了9个鼠标事件:
 click:当用户点击鼠标主键通常是指鼠标左键或按回车键时触发。

dbclick:用户双击鼠标时触发

mousedown:当用户按下鼠标任意一个键都会触发,这个事件是不能够通过键盘触发的。

mousemove:当鼠标在某元素周围移动时重复触发,该事件不能通过键盘事件触发。

mouseout:当鼠标离开元素时触发,这个事件不能通过键盘触发。

mouseover:当鼠标进入元素时触发,这个事件不能够通过键盘触发。

 mouseenter:类似“mouseover”,但不冒泡,而且当光标移到后代元素上不会触发。

mouseleave:类似“mouseout”,但不冒泡。在元素上方是不触发。

mouseup:当用户释放鼠标按键时触发,不能够通过键盘触发。

传递给鼠标事件处理程序的事件对象有clientX和clientY属性,它们指定了鼠标指针相对于包含窗口的坐标。加入窗口的滚动偏移量,就可以把鼠标位置转换成文档坐标。
页面上的所有元素都支持鼠标事件。除了mouseenter和mouseleave外,所有的事件都冒泡,并且他们的默认行为是可以被取消掉的。但取消鼠标事件的默认行为可能会影响到其他事件,因为有些鼠标事件是相互依赖的。

拖拉事件 

(1)drag事件
 drag事件在源对象被拖拉过程中触发。
(2)dragstart,dragend事件
 dragstart事件在用户开始用鼠标拖拉某个对象时触发,dragend事件在结束拖拉时触发。
(3)dragenter,dragleave事件
 dragenter事件在源对象拖拉进目标对象后,在目标对象上触发。dragleave事件在源对象离开目标对象后,在目标对象上触发。
(4)dragover事件
 dragover事件在源对象拖拉过另一个对象上方时,在后者上触发。
(5)drop事件

 当源对象被拖拉到目标对象上方,用户松开鼠标时,在目标对象上触发drop事件。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
基于jquery的滑动样例代码
Nov 20 Javascript
JQuery 返回布尔值Is()条件判断方法代码
May 14 Javascript
页面使用密码保护代码
Apr 10 Javascript
JavaScript的代码编写格式规范指南
Dec 07 Javascript
用JS生成UUID的方法实例
Mar 30 Javascript
全面解析Bootstrap中Carousel轮播的使用方法
Jun 13 Javascript
全面了解javascript三元运算符
Jun 27 Javascript
微信小程序页面间通信的5种方式
Mar 31 Javascript
Vue工程模板文件 webpack打包配置方法
Dec 26 Javascript
vue中设置、获取、删除cookie的方法
Sep 21 Javascript
layui数据表格重载实现往后台传参
Nov 15 Javascript
JS代码编译器Monaco使用方法
Jun 11 Javascript
jQuery实现简单的网页换肤效果示例
Sep 18 #Javascript
js完整倒计时代码分享
Sep 18 #Javascript
Javascript中常见的逻辑题和解决方法
Sep 17 #Javascript
js手动播放图片实现图片轮播效果
Sep 17 #Javascript
Bootstrap时间选择器datetimepicker和daterangepicker使用实例解析
Sep 17 #Javascript
AngularJS使用自定义指令替代ng-repeat的方法
Sep 17 #Javascript
Bootstrap Table表格一直加载(load)不了数据的快速解决方法
Sep 17 #Javascript
You might like
用php实现的获取网页中的图片并保存到本地的代码
2010/01/05 PHP
PHP基于curl模拟post提交json数据示例
2018/06/22 PHP
简单的无缝滚动程序-仅几行代码
2007/05/08 Javascript
JS.GetAllChild(element,deep,condition)使用介绍
2013/09/21 Javascript
指定区域的图片自动按比例缩小的js代码(防止页面被图片撑破)
2014/02/21 Javascript
浅谈JavaScript字符集
2014/05/22 Javascript
jQuery功能函数详解
2015/02/01 Javascript
js实现宇宙星空背景效果的方法
2015/03/03 Javascript
js实现瀑布流的三种方式比较
2020/06/28 Javascript
喜大普奔!jQuery发布 3.0 最终版
2016/06/12 Javascript
用js动态添加html元素,以及属性的简单实例
2016/07/19 Javascript
JavaScript Ajax实现异步通信
2016/12/14 Javascript
Three.js的使用及绘制基础3D图形详解
2017/04/27 Javascript
mpvue中使用flyjs全局拦截的实现代码
2018/09/13 Javascript
详解vuex状态管理模式
2018/11/01 Javascript
[03:40]DOTA2英雄梦之声_第01期_炼金术士
2014/06/23 DOTA
python批量下载图片的三种方法
2013/04/22 Python
Python导出DBF文件到Excel的方法
2015/07/25 Python
解决pyinstaller打包exe文件出现命令窗口一闪而过的问题
2018/10/31 Python
python抓取京东小米8手机配置信息
2018/11/13 Python
python mqtt 客户端的实现代码实例
2019/09/25 Python
python将数组n等分的实例
2019/12/02 Python
win10系统Anaconda和Pycharm的Tensorflow2.0之CPU和GPU版本安装教程
2019/12/03 Python
python每5分钟从kafka中提取数据的例子
2019/12/23 Python
Python json转字典字符方法实例解析
2020/04/13 Python
django 获取字段最大值,最新的记录操作
2020/08/09 Python
Banana Republic欧盟:美国都市简约风格的代表品牌
2018/05/09 全球购物
Java servlet面试题
2012/03/04 面试题
考察现实表现材料
2014/05/19 职场文书
汽车技术服务与贸易专业求职信
2014/07/20 职场文书
推广普通话共筑中国梦演讲稿
2014/09/21 职场文书
写给老师的感谢信
2015/01/20 职场文书
装修公司管理制度
2015/08/05 职场文书
2019年销售部季度工作计划3篇
2019/10/09 职场文书
如何利用Matlab制作一款真正的拼图小游戏
2021/05/11 Python
浅谈Redis位图(Bitmap)及Redis二进制中的问题
2021/07/15 Redis