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 相关文章推荐
jscript之List Excel Color Values
Jun 13 Javascript
当鼠标移动到图片上时跟随鼠标显示放大的图片效果
Jun 06 Javascript
javascript实现图片延迟加载方法汇总(三种方法)
Aug 27 Javascript
js表单元素checked、radio被选中的几种方法(详解)
Aug 22 Javascript
AngularJS表单验证中级篇(3)
Sep 28 Javascript
js鼠标按键事件和键盘按键事件用法实例汇总
Oct 03 Javascript
JavaScript正则表达式小结(test|match|search|replace|split|exec)
Dec 08 Javascript
Bootstrap DateTime Picker日历控件简单应用
Mar 25 Javascript
AngularJS改变元素显示状态
Apr 20 Javascript
vue.js 上传图片实例代码
Jun 22 Javascript
Javascript 对象(object)合并操作实例分析
Jul 30 Javascript
NProgress显示顶部进度条效果及使用详解
Sep 21 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 Google的translate API代码
2008/12/10 PHP
工厂模式在Zend Framework中应用介绍
2012/07/10 PHP
PHP中ini_set与ini_get用法实例
2014/11/04 PHP
微信公众号开发之微信公共平台消息回复类实例
2014/11/14 PHP
Yii2 rbac权限控制之rule教程详解
2016/06/23 PHP
laravel5.4利用163邮箱发送邮件的步骤详解
2017/09/22 PHP
PHP利用curl发送HTTP请求的实例代码
2020/07/09 PHP
Javascript 强制类型转换函数
2009/05/17 Javascript
javascript 节点遍历函数
2010/03/28 Javascript
javascript动态改变img的src属性图片不显示的解决方法
2010/10/20 Javascript
30个让人兴奋的视差滚动(Parallax Scrolling)效果网站
2012/03/04 Javascript
jQuery源码分析之Callbacks详解
2015/03/13 Javascript
Extjs实现下拉菜单效果
2016/04/01 Javascript
微信小程序加载更多 点击查看更多
2016/11/29 Javascript
vue.js移动端tab组件的封装实践实例
2017/06/30 Javascript
Vue2.0点击切换类名改变样式的方法
2018/08/22 Javascript
jQuery+PHP实现上传裁剪图片
2020/06/29 jQuery
微信小程序自定义可滑动日历界面
2018/12/28 Javascript
vue子传父关于.sync与$emit的实现
2019/11/05 Javascript
JS实现图片切换特效
2019/12/23 Javascript
vue-cli3项目配置eslint代码规范的完整步骤
2020/09/10 Javascript
python 获取文件列表(或是目录例表)
2009/03/25 Python
Python的垃圾回收机制深入分析
2014/07/16 Python
Python基础学习之常见的内建函数整理
2017/09/06 Python
局域网内python socket实现windows与linux间的消息传送
2019/04/19 Python
对YOLOv3模型调用时候的python接口详解
2019/08/26 Python
浅谈Python 函数式编程
2020/06/20 Python
使用css3背景渐变中的透明度来设置不同颜色的背景渐变
2014/03/31 HTML / CSS
法律进机关实施方案
2014/03/12 职场文书
教师专业自荐信
2014/05/31 职场文书
2014年商场国庆节活动策划方案
2014/09/16 职场文书
工作检讨书怎么写
2015/01/23 职场文书
教师廉政准则心得体会
2016/01/20 职场文书
2019军训心得体会
2019/06/27 职场文书
python执行js代码的方法
2021/05/13 Python
vue使用element-ui按需引入
2022/05/20 Vue.js