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 相关文章推荐
javascript脚本编程解决考试分数统计问题
Oct 18 Javascript
JavaScript 克隆数组最简单的方法
Feb 12 Javascript
jquery在项目中做复选框时遇到的一些问题笔记
Nov 17 Javascript
JS将所有对象s的属性复制给对象r(原生js+jquery)
Jan 25 Javascript
JQuery调用WebServices的方法和4个实例
May 06 Javascript
js实现数组转换成json
Jun 26 Javascript
js模仿php中strtotime()与date()函数实现方法
Aug 11 Javascript
Bootstrap的fileinput插件实现多文件上传的方法
Sep 05 Javascript
jquery.multiselect多选下拉框实现代码
Nov 11 Javascript
Node.js 使用命令行工具检查更新
Jun 08 Javascript
JavaScript实现的仿新浪微博原生态输入字数即时检查功能【兼容IE6】
Sep 26 Javascript
bootstrap Table服务端处理分页(后台是.net)
Oct 19 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文件操作实现代码分享
2011/09/01 PHP
CI框架入门示例之数据库取数据完整实现方法
2014/11/05 PHP
php递归遍历删除文件的方法
2015/04/17 PHP
PHP获取文件夹大小函数用法实例
2015/07/01 PHP
PHP中number_format()函数的用法讲解
2019/04/08 PHP
PHP实现统计代码行数小工具
2019/09/19 PHP
如何快速的呈现我们的网页的技巧整理
2007/07/01 Javascript
解析javascript 浏览器关闭事件
2013/07/08 Javascript
解析页面加载与js函数的执行 onload or ready
2013/12/12 Javascript
js的toUpperCase方法用法实例
2015/01/27 Javascript
javascript实现在网页中运行本地程序的方法
2016/02/03 Javascript
JavaScript组成、引入、输出、运算符基础知识讲解
2016/12/08 Javascript
vue + axios get下载文件功能
2019/09/25 Javascript
JavaScript定时器常见用法实例分析
2019/11/15 Javascript
vuejs中父子组件之间通信方法实例详解
2020/01/17 Javascript
vue iview 隐藏Table组件里的某一列操作
2020/11/13 Javascript
原生JavaScript实现轮播图
2021/01/10 Javascript
利用Python自动监控网站并发送邮件告警的方法
2016/08/24 Python
python读取视频流提取视频帧的两种方法
2020/10/22 Python
Python中文编码知识点
2019/02/18 Python
pandas的to_datetime时间转换使用及学习心得
2019/08/11 Python
用Python批量把文件复制到另一个文件夹的实现方法
2019/08/16 Python
python Opencv计算图像相似度过程解析
2019/12/03 Python
解决Tensorboard可视化错误:不显示数据 No scalar data was found
2020/02/15 Python
Python操作Jira库常用方法解析
2020/04/10 Python
html5 兼容IE6结构的实现代码
2012/05/14 HTML / CSS
使用HTML5做个画图板的方法介绍
2013/05/03 HTML / CSS
canvas环形倒计时组件的示例代码
2018/06/14 HTML / CSS
印度购物网站:TATA CLiQ
2017/11/23 全球购物
Bally巴利英国官网:经典瑞士鞋履、手袋及配饰奢侈品牌
2018/05/07 全球购物
回门宴新郎答谢词
2014/01/12 职场文书
优秀大学生的自我评价
2014/01/16 职场文书
安全检查与奖惩制度
2014/01/23 职场文书
高三毕业典礼主持词
2014/03/27 职场文书
小学安全工作汇报材料
2014/08/19 职场文书
利用js实现简单开关灯代码
2021/11/23 Javascript