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 相关文章推荐
prototype.js的Ajax对象
Sep 23 Javascript
Jquery实现无刷新DropDownList联动实现代码
Mar 08 Javascript
表格奇偶行设置不同颜色的核心JS代码
Dec 24 Javascript
根据配置文件加载js依赖模块
Dec 29 Javascript
Bootstrap中的Dropdown下拉菜单更改为悬停(hover)触发
Aug 31 Javascript
Node.js检测端口(port)是否被占用的简单示例
Sep 29 Javascript
JS实现的验证身份证及获取地区功能示例
Jan 16 Javascript
JavaScript数据结构之双向链表和双向循环链表的实现
Nov 28 Javascript
Vue中自定义全局组件的实现方法
Dec 08 Javascript
快速搭建vue2.0+boostrap项目的方法
Apr 09 Javascript
解决vue router组件状态刷新消失的问题
Aug 01 Javascript
layer父页获取弹出层输入框里面的值方法
Sep 02 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 获取MySQL数据库里所有表的实现代码
2011/07/13 PHP
php中http_build_query 的一个问题
2012/03/25 PHP
PHP实现驼峰样式字符串(首字母大写)转换成下划线样式字符串的方法示例
2017/08/10 PHP
Javascript实例教程(19) 使用HoTMetal(3)
2006/12/23 Javascript
jquery中dom操作和事件的实例学习 下拉框应用
2011/12/01 Javascript
深入理解JavaScript系列(13) This? Yes,this!
2012/01/18 Javascript
js控制表单不能输入空格的小例子
2013/11/20 Javascript
JS动态增加删除UL节点LI及相关内容示例
2014/05/21 Javascript
JS实现清除指定cookies的方法
2014/09/20 Javascript
jQuery显示和隐藏 常用的状态判断方法
2015/01/29 Javascript
javascript中 try catch用法
2015/08/16 Javascript
easyui messager alert 三秒后自动关闭提示的实例
2016/11/07 Javascript
Ionic2系列之使用DeepLinker实现指定页面URL
2016/11/21 Javascript
原生javascript实现读写CSS样式的方法详解
2017/02/20 Javascript
js计算两个日期间的天数月的实例代码
2018/09/20 Javascript
Vue 实现从文件中获取文本信息的方法详解
2019/10/16 Javascript
pycharm 使用心得(三)Hello world!
2014/06/05 Python
Python写的Socks5协议代理服务器
2014/08/06 Python
Python2.x和3.x下maketrans与translate函数使用上的不同
2015/04/13 Python
python+matplotlib绘制旋转椭圆实例代码
2018/01/12 Python
python根据unicode判断语言类型实例代码
2018/01/17 Python
Django压缩静态文件的实现方法详析
2018/08/26 Python
Python中调用其他程序的方式详解
2019/08/06 Python
Python定时任务随机时间执行的实现方法
2019/08/14 Python
python实现单张图像拼接与批量图片拼接
2020/03/23 Python
canvas版人体时钟的实现示例
2021/01/29 HTML / CSS
美国户外生活方式品牌:Eddie Bauer
2016/12/28 全球购物
英国时尚运动品牌的合集:The Sports Edit
2017/12/20 全球购物
一些PHP的面试题
2015/05/06 面试题
应届生财务管理求职信
2013/11/06 职场文书
《花木兰》教学反思
2014/04/09 职场文书
打架赔偿协议书范本
2014/10/26 职场文书
2016大学生优秀志愿者事迹材料
2016/02/25 职场文书
创业计划书之水果店
2019/07/18 职场文书
python实现简易自习室座位预约系统
2021/06/30 Python
Win11 21h2可以升级22h2吗?看看你的电脑符不符合要求
2022/07/07 数码科技